<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <meta name="renderer" content="webkit">
  <meta http-equiv="X-UA-Compatible" content="IE=edge" >
  <link rel="dns-prefetch" href="http://example.com">
  <title>视频监控系统 FFmpeg方案 | Hexo</title>
  <meta name="generator" content="hexo-theme-yilia-plus">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
  <meta name="description" content="1.1 FFmpeg 的简易理解误区：我们以为mp4就代表了音频、视频的压缩格式，其实不是  Mp4只是一种封装格式 里面有音频数据、视频数据 音频数据有自己的压缩格式，还不止一种 视频数据也有自己的压缩格式，还不止一种  参考文章视音频编解码技术零基础学习方法https:&#x2F;&#x2F;blog.csdn.net&#x2F;leixiaohua1020&#x2F;article&#x2F;details&#x2F;18893769  从摄像头得">
<meta property="og:type" content="article">
<meta property="og:title" content="视频监控系统 FFmpeg方案">
<meta property="og:url" content="http://example.com/2021/08/10/%E7%9B%91%E6%8E%A7%E5%BC%80%E5%8F%91/%E8%A7%86%E9%A2%91%E7%9B%91%E6%8E%A7%E7%B3%BB%E7%BB%9F%20FFmpeg%E6%96%B9%E6%A1%88/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="1.1 FFmpeg 的简易理解误区：我们以为mp4就代表了音频、视频的压缩格式，其实不是  Mp4只是一种封装格式 里面有音频数据、视频数据 音频数据有自己的压缩格式，还不止一种 视频数据也有自己的压缩格式，还不止一种  参考文章视音频编解码技术零基础学习方法https:&#x2F;&#x2F;blog.csdn.net&#x2F;leixiaohua1020&#x2F;article&#x2F;details&#x2F;18893769  从摄像头得">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101931622.png">
<meta property="og:image" content="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101932383.png">
<meta property="og:image" content="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101933069.png">
<meta property="og:image" content="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101934297.png">
<meta property="og:image" content="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101935915.png">
<meta property="og:image" content="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101936179.png">
<meta property="og:image" content="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101937477.png">
<meta property="og:image" content="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101938051.png">
<meta property="og:image" content="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101939426.png">
<meta property="og:image" content="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101945418.png">
<meta property="og:image" content="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101946768.png">
<meta property="og:image" content="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108121212888.png">
<meta property="og:image" content="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108102026317.png">
<meta property="og:image" content="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108120006569.png">
<meta property="og:image" content="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108121548864.png">
<meta property="article:published_time" content="2021-08-10T15:00:00.000Z">
<meta property="article:modified_time" content="2021-08-12T09:13:40.356Z">
<meta property="article:author" content="Moses Yu">
<meta property="article:tag" content="视频监控系统">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101931622.png">
  
    <link rel="alternative" href="/blog/atom.xml" title="Hexo" type="application/atom+xml">
  
  
    <link rel="icon" href="/blog/favicon.ico">
  
  
    <link rel="apple-touch-icon" href="/blog/apple-touch-icon-180x180.png">
  
  <link rel="stylesheet" type="text/css" href="/blog/./main.a5fda8.css">
  <style type="text/css">
    
    #container.show {
      background: linear-gradient(200deg,#a0cfe4,#e8c37e);
    }
  </style>
  

  

  
    
 	  <script src="/blog/lib/clickLove.js"></script>
  
  


  

</head>

<body>
  <div id="container" q-class="show:isCtnShow">
    <canvas id="anm-canvas" class="anm-canvas"></canvas>
    <div class="left-col" q-class="show:isShow">
      


<div class="overlay" style="background: #4d4d4d;"></div>
<div class="intrude-less">
	<header id="header" class="inner">
		<a href="/blog/" class="profilepic">
			<img src="/blog/img/head.png" class="js-avatar">
		</a>
		<hgroup>
			<h1 class="header-author"><a href="/blog/">Moses Yu</a></h1>
		</hgroup>
		

		<nav class="header-menu">
			<ul>
			
				<li><a href="/blog/" target="_blank">主页</a></li>
			
			</ul>
		</nav>
		<nav class="header-smart-menu">
			
				
					<a q-on="click: openSlider(e, 'innerArchive')" href="javascript:void(0)">所有文章</a>
				
			
				
					<a q-on="click: openSlider(e, 'friends')" href="javascript:void(0)">友链</a>
				
			
				
					<a q-on="click: openSlider(e, 'aboutme')" href="javascript:void(0)">关于我</a>
				
			
		</nav>
		<nav class="header-nav">
			<div class="social">
				
					
						<a class="github" href="https://github.com/yzm65580952" 
												title="GitHub" target="_blank"><i class="icon-github"></i></a>
					
				
					
						<a class="gitee" href="https://gitee.com/yuzhongmeng" 
												title="gitee" target="_blank"><i class="icon-gitee"></i></a>
					
				
					
						<a class="bilibili" href="https://space.bilibili.com/2607595" 
												title="bilibili" target="_blank"><i class="icon-bilibili"></i></a>
					
				
					
						<a class="mail" href="/blog/619372559@qq.com" 
												title="Email" target="_blank"><i class="icon-mail"></i></a>
					
				
			</div>
		
			
			
			
			
			<div>
				<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width="240" height="86" src="//music.163.com/outchain/player?type=2&id=1401040007&auto=0&height=66"></iframe>
			</div>
			
				
				<p style="font-size: 12px;">这似乎是首纯音乐，请尽情的欣赏它吧！<p>
			
		
		</nav>
	</header>		
</div>

    </div>
    <div class="mid-col" q-class="show:isShow,hide:isShow|isFalse">
      
      
<nav id="mobile-nav">
  	<div class="overlay js-overlay" style="background: #4d4d4d"></div>
	<div class="btnctn js-mobile-btnctn">
  		<div class="slider-trigger list" q-on="click: openSlider(e)"><i class="icon icon-sort"></i></div>
	</div>
	<div class="intrude-less">
		<header id="header" class="inner">
			<div class="profilepic">
				<a href="/blog/">
					<img src="/blog/img/head.png" class="js-avatar">
				</a>
			</div>
			<hgroup>
			  <h1 class="header-author js-header-author">Moses Yu</h1>
			</hgroup>
			
			
			
				
			
			
			
			<nav class="header-nav">
				<div class="social">
					
						
						<a class="github" target="_blank" 
							href="https://github.com/yzm65580952" title="GitHub"><i class="icon-github"></i></a>
						
					
						
						<a class="gitee" target="_blank" 
							href="https://gitee.com/yuzhongmeng" title="gitee"><i class="icon-gitee"></i></a>
						
					
						
						<a class="bilibili" target="_blank" 
							href="https://space.bilibili.com/2607595" title="bilibili"><i class="icon-bilibili"></i></a>
						
					
						
						<a class="mail" target="_blank" 
							href="/blog/619372559@qq.com" title="Email"><i class="icon-mail"></i></a>
						
					
				</div>
			</nav>

			<nav class="header-menu js-header-menu">
				<ul style="width: 50%">
				
				
					<li style="width: 100%"><a href="/blog/">主页</a></li>
		        
				</ul>
			</nav>
		</header>				
	</div>
	<div class="mobile-mask" style="display:none" q-show="isShow"></div>
</nav>

      <div id="wrapper" class="body-wrap">
        <div class="menu-l">
          <div class="canvas-wrap">
            <canvas data-colors="#eaeaea" data-sectionHeight="100" data-contentId="js-content" id="myCanvas1"
              class="anm-canvas"></canvas>
          </div>
          <div id="js-content" class="content-ll">
            <article id="post-监控开发/视频监控系统 FFmpeg方案" class="article article-type-post " itemscope itemprop="blogPost">
  <div class="article-inner">
    
      <header class="article-header">
  
  
    <h1 class="article-title" itemprop="name">
      视频监控系统 FFmpeg方案
    </h1>
  


  
  
        
        <span id="busuanzi_container_page_pv" style='display:none' class="archive-article-date">
              <i class="icon-smile icon"></i> 阅读数：<span id="busuanzi_value_page_pv"></span>次
        </span>

<a href="/blog/2021/08/10/%E7%9B%91%E6%8E%A7%E5%BC%80%E5%8F%91/%E8%A7%86%E9%A2%91%E7%9B%91%E6%8E%A7%E7%B3%BB%E7%BB%9F%20FFmpeg%E6%96%B9%E6%A1%88/" class="archive-article-date">
        <time datetime="2021-08-10T15:00:00.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2021-08-10</time>
</a>

  
  
    
<div style="margin-top:10px;">
  <span class="post-time">
    <span class="post-meta-item-icon">
      <!-- fonts.scss -->
      <!-- 百度字体平台:http://fontstore.baidu.com/static/editor/index.html -->
      <i class="icon-statistics"></i>
      <span class="post-meta-item-text"> 字数统计:</span>
      <span class="post-count">24.4k字</span>
    </span>
  </span>

  <span class="post-time">
    &nbsp; | &nbsp;
    <span class="post-meta-item-icon">
      <i class="icon-book icon"></i>
      <span class="post-meta-item-text"> 阅读时长≈</span>
      <span class="post-count">144分</span>
    </span>
  </span>
</div>


  
  </header>
  
  <div class="article-entry" itemprop="articleBody">
    
    <p><img src="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101931622.png"></p>
<h2 id="1-1-FFmpeg-的简易理解"><a href="#1-1-FFmpeg-的简易理解" class="headerlink" title="1.1 FFmpeg 的简易理解"></a>1.1 FFmpeg 的简易理解</h2><p><img src="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101932383.png"><br>误区：我们以为mp4就代表了音频、视频的压缩格式，其实不是</p>
<ul>
<li>Mp4只是一种封装格式</li>
<li>里面有音频数据、视频数据</li>
<li>音频数据有自己的压缩格式，还不止一种</li>
<li>视频数据也有自己的压缩格式，还不止一种</li>
</ul>
<p>参考文章<br>视音频编解码技术零基础学习方法<br><a target="_blank" rel="noopener" href="https://blog.csdn.net/leixiaohua1020/article/details/18893769">https://blog.csdn.net/leixiaohua1020/article/details/18893769</a></p>
<p><img src="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101933069.png"></p>
<p>从摄像头得到的原始数据太大，不易传输，需要压缩</p>
<ul>
<li>压缩的方法有很多种：格式不同，编码器不同，这里对应视频编码器</li>
</ul>
<p>从声卡得到的原始数据太大，不易传输，需要压缩</p>
<ul>
<li>压缩的方法有很多种：格式不同，编码器不同，这里对应音频编码器</li>
</ul>
<p>把这些压缩后，即编码后的视频数据、音频数据合并在一起：复用、MUX，就得到了MP4等文件<br>参考文章<br>视音频编解码技术零基础学习方法<br><a target="_blank" rel="noopener" href="https://blog.csdn.net/leixiaohua1020/article/details/18893769">https://blog.csdn.net/leixiaohua1020/article/details/18893769</a><br><img src="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101934297.png"></p>
<p><img src="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101935915.png"></p>
<h2 id="1-2-FFmpeg的组成"><a href="#1-2-FFmpeg的组成" class="headerlink" title="1.2 FFmpeg的组成"></a>1.2 FFmpeg的组成</h2><p>ffmpeg 基本用法<br><a target="_blank" rel="noopener" href="https://www.jianshu.com/p/3c8c4a892f3c">https://www.jianshu.com/p/3c8c4a892f3c</a></p>
<p><img src="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101936179.png"></p>
<p><img src="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101937477.png"></p>
<h2 id="1-3-FFmpeg处理音视频的过程"><a href="#1-3-FFmpeg处理音视频的过程" class="headerlink" title="1.3 FFmpeg处理音视频的过程"></a>1.3 FFmpeg处理音视频的过程</h2><p><img src="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101938051.png"></p>
<p>用Filter(过滤器)来处理:<br>旋转、拉伸<br>添加LOGO、消除LOGO等等</p>
<h2 id="1-4-FFmpeg的常用参数"><a href="#1-4-FFmpeg的常用参数" class="headerlink" title="1.4 FFmpeg的常用参数"></a>1.4 FFmpeg的常用参数</h2><p><img src="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101939426.png"></p>
<h2 id="1-5-编译FFmpeg-到内核"><a href="#1-5-编译FFmpeg-到内核" class="headerlink" title="1.5 编译FFmpeg 到内核"></a>1.5 编译FFmpeg 到内核</h2><p>设置交叉编译工具链<br>在Buildroot根目录<br>make menuconfig<br>如图选择ffmpeg<br>执行make<br>这会在Buildroot的dl/ffmpeg目录下自动下载源码，并编译<br>结果保存在output/images目录下，有emmc.img, sdcard.img，可以直接烧写到板能的EMMC或SD卡上</p>
<h2 id="1-6-运行FFmpeg-录像"><a href="#1-6-运行FFmpeg-录像" class="headerlink" title="1.6 运行FFmpeg 录像"></a>1.6 运行FFmpeg 录像</h2><p>在开发板上安装好ffmpeg后：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">ffmpeg -f v4l2 -framerate 10 -i /dev/video1 -q 10  my.mp4</span><br><span class="line"><span class="meta">#</span><span class="bash">-framerate 10 一秒10帧</span></span><br><span class="line"><span class="meta">#</span><span class="bash">-q 10 质量10</span></span><br><span class="line"><span class="meta">#</span><span class="bash">-f 输入视频的格式</span></span><br><span class="line"><span class="meta">#</span><span class="bash">它会把摄像头的数据录制为my.mp4 把my.mp4复制到PC机，播放</span></span><br></pre></td></tr></table></figure>
<p>更多用法：<br>ffmpeg基础使用：<a target="_blank" rel="noopener" href="https://www.jianshu.com/p/ddafe46827b7">https://www.jianshu.com/p/ddafe46827b7</a><br>给新手的 20 多个 FFmpeg 命令示例：<a target="_blank" rel="noopener" href="https://zhuanlan.zhihu.com/p/67878761">https://zhuanlan.zhihu.com/p/67878761</a><br>建议在Windows下练习：<br>下载static版本：<a target="_blank" rel="noopener" href="https://ffmpeg.zeranoe.com/builds/">https://ffmpeg.zeranoe.com/builds/</a><br>在命令行中练习ffmpeg</p>
<h2 id="2-1-Nginx是什么"><a href="#2-1-Nginx是什么" class="headerlink" title="2.1 Nginx是什么"></a>2.1 Nginx是什么</h2><p>一套开源软件，纯C语言编写，效率高<br>HTTP和反向代理web服务器，同时也是一个 IMAP、POP3、SMTP 代理服务器<br>稳定、高效，支持高并发<br>即使强如阿里巴巴，也是使用Nginx： <a target="_blank" rel="noopener" href="http://tengine.taobao.org/">http://tengine.taobao.org</a> 它就是在Nginx的基础上，针对大访问量网站的需求，添加了很多高级功能和特性。<br>我们只关注：Nginx可以作为流体服务器，支持RTMP、HTTPFLV、HLS等协议</p>
<p><img src="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101945418.png"></p>
<h2 id="2-2-三种WEB服务器的比较"><a href="#2-2-三种WEB服务器的比较" class="headerlink" title="2.2 三种WEB服务器的比较"></a>2.2 三种WEB服务器的比较</h2><p><img src="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108101946768.png"></p>
<h2 id="2-3-Nginx在流媒体方案中的位置"><a href="#2-3-Nginx在流媒体方案中的位置" class="headerlink" title="2.3 Nginx在流媒体方案中的位置"></a>2.3 Nginx在流媒体方案中的位置</h2><p><img src="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108121212888.png"><br>推流端</p>
<ul>
<li>FFmpeg使用RTMP协议向Nginx推流</li>
</ul>
<p>拉流端</p>
<ul>
<li>VLC播放器使用RTMP或HTTPFLV协议从Nginx拉流</li>
<li>浏览器使用HTTPFLV协议从Nginx拉流(安装flv.js)</li>
</ul>
<h2 id="2-4-让Ngnix支持RTMP、HTTPFLV协议"><a href="#2-4-让Ngnix支持RTMP、HTTPFLV协议" class="headerlink" title="2.4 让Ngnix支持RTMP、HTTPFLV协议"></a>2.4 让Ngnix支持RTMP、HTTPFLV协议</h2><p>nginx-http-flv-module：在nginx-rtmp-module的基础上，实现了HTTPFLV，并覆盖nginx-rtmp-module的所有功能<br>第3方模块源码：<br><a target="_blank" rel="noopener" href="https://github.com/winshining/nginx-http-flv-module/">https://github.com/winshining/nginx-http-flv-module/</a><br>参考资料<br><a target="_blank" rel="noopener" href="https://github.com/winshining/nginx-http-flv-module/blob/master/README.CN.md">https://github.com/winshining/nginx-http-flv-module/blob/master/README.CN.md</a></p>
<h2 id="2-5-移植Nginx"><a href="#2-5-移植Nginx" class="headerlink" title="2.5 移植Nginx"></a>2.5 移植Nginx</h2><ol>
<li><p>设置交叉编译工具链</p>
</li>
<li><p>下载第3方模块：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">mkdir  dl/nginx #在Buildroot目录下，创建目录：</span><br><span class="line">cd  dl/nginx  &amp;&amp;  git clone https://github.com/winshining/nginx-http-flv-module.git</span><br><span class="line"></span><br></pre></td></tr></table></figure></li>
<li><p>make menuconfig<br>把原来的lighttpd去掉，否则板子也会自动启动它，就会有两个HTTP服务了：lighttpd, nginx<br>如图选择Nginx，建议把所有功能都选上并且设置额外的参数，在“additional modules”中添加： $(TOPDIR)/dl/nginx/nginx-http-flv-module<br><img src="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108102026317.png"></p>
</li>
<li><p>最后执行(先删除之前编译的nginx，我发现有时设置的第3方模块不起作用，删除后再make就可以了)：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">rm -rf output/build/nginx-1.15.7   &amp;&amp;  make</span><br></pre></td></tr></table></figure></li>
<li><p>这会在Buildroot的dl/nginx目录下自动下载源码，并编译</p>
</li>
<li><p>结果保存在output/images目录下，有emmc.img, sdcard.img，可以直接烧写到板能的EMMC或SD卡上</p>
</li>
</ol>
<h2 id="2-6-配置-Nginx服务"><a href="#2-6-配置-Nginx服务" class="headerlink" title="2.6 配置 Nginx服务"></a>2.6 配置 Nginx服务</h2><p>vi /etc/nginx/nginx.conf</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash">user  nobody;</span></span><br><span class="line">worker_processes  auto;# 1.1该成auto 原先是1</span><br><span class="line"><span class="meta">#</span><span class="bash">error_log  logs/error.log;</span></span><br><span class="line"><span class="meta">#</span><span class="bash">error_log  logs/error.log  notice;</span></span><br><span class="line"><span class="meta">#</span><span class="bash">error_log  logs/error.log  info;</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash">pid        logs/nginx.pid;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">events &#123;</span><br><span class="line">    worker_connections  1024;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash">1.2 增加rtmp服务器的配置</span></span><br><span class="line">rtmp &#123;</span><br><span class="line">	server &#123;</span><br><span class="line">		listen 1935;#listen the rtmp port</span><br><span class="line">		chunk_size 4096;</span><br><span class="line">		</span><br><span class="line">		application live&#123;</span><br><span class="line">			allow publish 127.0.0.1;</span><br><span class="line">			live on;</span><br><span class="line">			record off;</span><br><span class="line">			meta copy;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">http &#123;</span><br><span class="line">    include       mime.types;</span><br><span class="line">    default_type  application/octet-stream;</span><br><span class="line"></span><br><span class="line">    #log_format  main  &#x27;$remote_addr - $remote_user [$time_local] &quot;$request&quot; &#x27;</span><br><span class="line">    #                  &#x27;$status $body_bytes_sent &quot;$http_referer&quot; &#x27;</span><br><span class="line">    #                  &#x27;&quot;$http_user_agent&quot; &quot;$http_x_forwarded_for&quot;&#x27;;</span><br><span class="line"></span><br><span class="line">    #access_log  logs/access.log  main;</span><br><span class="line"></span><br><span class="line">    sendfile        on;</span><br><span class="line">    #tcp_nopush     on;</span><br><span class="line"></span><br><span class="line">    #keepalive_timeout  0;</span><br><span class="line">    keepalive_timeout  65;</span><br><span class="line"></span><br><span class="line">    #gzip  on;</span><br><span class="line"></span><br><span class="line">    server &#123;</span><br><span class="line">        listen       80;</span><br><span class="line">        server_name  localhost;</span><br><span class="line"></span><br><span class="line">        #charset koi8-r;</span><br><span class="line"></span><br><span class="line">        #access_log  logs/host.access.log  main;</span><br><span class="line"></span><br><span class="line">        location / &#123;</span><br><span class="line">            root   html;</span><br><span class="line">            index  index.html index.htm;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        #error_page  404              /404.html;</span><br><span class="line"></span><br><span class="line">        # redirect server error pages to the static page /50x.html</span><br><span class="line">        #</span><br><span class="line">        error_page   500 502 503 504  /50x.html;</span><br><span class="line">        location = /50x.html &#123;</span><br><span class="line">            root   html;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">      	#1.3 增加flv_live接口 支持浏览器用http-flv协议播放</span><br><span class="line"><span class="meta">		#</span><span class="bash">以免rtmp端口被墙</span></span><br><span class="line"></span><br><span class="line">      	location /test &#123;</span><br><span class="line">      		flv_live on;</span><br><span class="line">      		chunked_transfer_encoding on;</span><br><span class="line">      		add_header &#x27;Access-Control-Allow-Origin&#x27; &#x27;*&#x27;;</span><br><span class="line">      		add_header &#x27;Access-Control-Allow-Credentials&#x27; &#x27;true&#x27;;</span><br><span class="line">      	&#125;</span><br><span class="line"></span><br><span class="line">        # proxy the PHP scripts to Apache listening on 127.0.0.1:80</span><br><span class="line">        #</span><br><span class="line">        #location ~ \.php$ &#123;</span><br><span class="line">        #    proxy_pass   http://127.0.0.1;</span><br><span class="line">        #&#125;</span><br><span class="line"></span><br><span class="line">        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000</span><br><span class="line">        #</span><br><span class="line">        #location ~ \.php$ &#123;</span><br><span class="line">        #    root           html;</span><br><span class="line">        #    fastcgi_pass   127.0.0.1:9000;</span><br><span class="line">        #    fastcgi_index  index.php;</span><br><span class="line">        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;</span><br><span class="line">        #    include        fastcgi_params;</span><br><span class="line">        #&#125;</span><br><span class="line"></span><br><span class="line">        # deny access to .htaccess files, if Apache&#x27;s document root</span><br><span class="line">        # concurs with nginx&#x27;s one</span><br><span class="line">        #</span><br><span class="line">        #location ~ /\.ht &#123;</span><br><span class="line">        #    deny  all;</span><br><span class="line">        #&#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    # another virtual host using mix of IP-, name-, and port-based configuration</span><br><span class="line">    #</span><br><span class="line">    #server &#123;</span><br><span class="line">    #    listen       8000;</span><br><span class="line">    #    listen       somename:8080;</span><br><span class="line">    #    server_name  somename  alias  another.alias;</span><br><span class="line"></span><br><span class="line">    #    location / &#123;</span><br><span class="line">    #        root   html;</span><br><span class="line">    #        index  index.html index.htm;</span><br><span class="line">    #    &#125;</span><br><span class="line">    #&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    # HTTPS server</span><br><span class="line">    #</span><br><span class="line">    #server &#123;</span><br><span class="line">    #    listen       443 ssl;</span><br><span class="line">    #    server_name  localhost;</span><br><span class="line"></span><br><span class="line">    #    ssl_certificate      cert.pem;</span><br><span class="line">    #    ssl_certificate_key  cert.key;</span><br><span class="line"></span><br><span class="line">    #    ssl_session_cache    shared:SSL:1m;</span><br><span class="line">    #    ssl_session_timeout  5m;</span><br><span class="line"></span><br><span class="line">    #    ssl_ciphers  HIGH:!aNULL:!MD5;</span><br><span class="line">    #    ssl_prefer_server_ciphers  on;</span><br><span class="line"></span><br><span class="line">    #    location / &#123;</span><br><span class="line">    #        root   html;</span><br><span class="line">    #        index  index.html index.htm;</span><br><span class="line">    #    &#125;</span><br><span class="line">    #&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>重新拉起<br>   /etc/init.d/S50nginx restart</p>
<h2 id="3-1-实验1-推送摄像头数据后-拉取rtmp流"><a href="#3-1-实验1-推送摄像头数据后-拉取rtmp流" class="headerlink" title="3.1 实验1 推送摄像头数据后 拉取rtmp流"></a>3.1 实验1 推送摄像头数据后 拉取rtmp流</h2><h3 id="3-1-1-推流"><a href="#3-1-1-推流" class="headerlink" title="3.1.1 推流"></a>3.1.1 推流</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ffmpeg -f v4l2 -framerate 10 -i /dev/video1 -q 10  -f flv rtmp://127.0.0.1/live/wei</span><br></pre></td></tr></table></figure>
<h3 id="3-1-2-拉流"><a href="#3-1-2-拉流" class="headerlink" title="3.1.2 拉流"></a>3.1.2 拉流</h3><p>VLC播放器中点击“媒体”-&gt;“打开网络串流”，输入：rtmp://192.168.1.6/live/wei  ，就可以播放了</p>
<h3 id="3-1-3-实验效果"><a href="#3-1-3-实验效果" class="headerlink" title="3.1.3 实验效果"></a>3.1.3 实验效果</h3><iframe src="http://player.bilibili.com/player.html?aid=974787152&bvid=BV1744y1y7Lu&cid=387265024&page=1" scrolling="no" border="0" width="800px" height="600px" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>

<h3 id="3-1-4-问题"><a href="#3-1-4-问题" class="headerlink" title="3.1.4 问题"></a>3.1.4 问题</h3><p>IMX6ULL cup性能太弱，视频采集阶段处理不过来，所以在VLC播放器里看到的视频很卡，很滞后<br>具体优化的办法可以考虑 增加硬件加速 。</p>
<p>本人的本职工作搞网关开发的，暂时没有精力再深入下去了。感兴趣的朋友以看看下面的资料<br><a target="_blank" rel="noopener" href="https://blog.csdn.net/brucexu1978/article/details/7471689">https://blog.csdn.net/brucexu1978/article/details/7471689</a><br><a target="_blank" rel="noopener" href="https://max.book118.com/html/2017/0608/112387487.shtm">https://max.book118.com/html/2017/0608/112387487.shtm</a></p>
<h2 id="3-2-实验2-推送视频后-拉取-trmp-流"><a href="#3-2-实验2-推送视频后-拉取-trmp-流" class="headerlink" title="3.2 实验2 推送视频后 拉取 trmp 流"></a>3.2 实验2 推送视频后 拉取 trmp 流</h2><h3 id="3-2-1-推流"><a href="#3-2-1-推流" class="headerlink" title="3.2.1 推流"></a>3.2.1 推流</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ffmpeg -re -i war.mp4 -vcodec copy -acodec copy -f flv rtmp://127.0.0.1/live/wei</span><br><span class="line"><span class="meta">#</span><span class="bash">可带上这个参数实现 循环推流 -stream_loop -1</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h3 id="3-2-2-拉流"><a href="#3-2-2-拉流" class="headerlink" title="3.2.2 拉流"></a>3.2.2 拉流</h3><p>同 3.1.2</p>
<h3 id="3-2-3-实验效果"><a href="#3-2-3-实验效果" class="headerlink" title="3.2.3 实验效果"></a>3.2.3 实验效果</h3><p>可以看到还是很流畅的，说明 实验1 的瓶颈在于处理摄像头的数据</p>
<iframe src="http://player.bilibili.com/player.html?aid=419768648&bvid=BV1e3411z7kN&cid=387265640&page=1" scrolling="no" border="0" width="800px" height="600px" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>

<h3 id="3-3-实验3-推送视频后使用-httpflv-flv-js-拉流"><a href="#3-3-实验3-推送视频后使用-httpflv-flv-js-拉流" class="headerlink" title="3.3 实验3 推送视频后使用 httpflv+flv.js 拉流"></a>3.3 实验3 推送视频后使用 httpflv+flv.js 拉流</h3><h3 id="3-3-1-推流"><a href="#3-3-1-推流" class="headerlink" title="3.3.1 推流"></a>3.3.1 推流</h3><p> 同3.2.1</p>
<h3 id="3-3-2-html-网页代码的实现"><a href="#3-3-2-html-网页代码的实现" class="headerlink" title="3.3.2 html 网页代码的实现"></a>3.3.2 html 网页代码的实现</h3><ol>
<li> 获取 flv.js 插件</li>
<li>拉流<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br></pre></td><td class="code"><pre><span class="line">  <span class="meta">&lt;!DOCTYPE <span class="meta-keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">content</span>=<span class="string">&quot;text/html; charset=utf-8&quot;</span> <span class="attr">http-equiv</span>=<span class="string">&quot;Content-Type&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>flv.js demo<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">style</span>&gt;</span></span><br><span class="line"><span class="css">        <span class="selector-class">.mainContainer</span> &#123;</span></span><br><span class="line">            display: block;</span><br><span class="line">            width: 1024px;</span><br><span class="line">            margin-left: auto;</span><br><span class="line">            margin-right: auto;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line"><span class="css">        <span class="selector-class">.urlInput</span> &#123;</span></span><br><span class="line">            display: block;</span><br><span class="line">            width: 100%;</span><br><span class="line">            margin-left: auto;</span><br><span class="line">            margin-right: auto;</span><br><span class="line">            margin-top: 8px;</span><br><span class="line">            margin-bottom: 8px;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line"><span class="css">        <span class="selector-class">.centeredVideo</span> &#123;</span></span><br><span class="line">            display: block;</span><br><span class="line">            width: 100%;</span><br><span class="line">            height: 576px;</span><br><span class="line">            margin-left: auto;</span><br><span class="line">            margin-right: auto;</span><br><span class="line">            margin-bottom: auto;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line"><span class="css">        <span class="selector-class">.controls</span> &#123;</span></span><br><span class="line">            display: block;</span><br><span class="line">            width: 100%;</span><br><span class="line">            text-align: left;</span><br><span class="line">            margin-left: auto;</span><br><span class="line">            margin-right: auto;</span><br><span class="line">            margin-top: 8px;</span><br><span class="line">            margin-bottom: 10px;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line"><span class="css">        <span class="selector-class">.logcatBox</span> &#123;</span></span><br><span class="line"><span class="css">            <span class="selector-tag">border-color</span>: <span class="selector-id">#CCCCCC</span>;</span></span><br><span class="line">            font-size: 11px;</span><br><span class="line">            font-family: Menlo, Consolas, monospace;</span><br><span class="line">            display: block;</span><br><span class="line">            width: 100%;</span><br><span class="line">            text-align: left;</span><br><span class="line">            margin-left: auto;</span><br><span class="line">            margin-right: auto;</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    </span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;mainContainer&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">video</span> <span class="attr">name</span>=<span class="string">&quot;videoElement&quot;</span> <span class="attr">class</span>=<span class="string">&quot;centeredVideo&quot;</span> <span class="attr">id</span>=<span class="string">&quot;videoElement&quot;</span> <span class="attr">controls</span> <span class="attr">width</span>=<span class="string">&quot;1024&quot;</span> <span class="attr">height</span>=<span class="string">&quot;576&quot;</span> <span class="attr">autoplay</span>&gt;</span></span><br><span class="line">            Your browser is too old which doesn&#x27;t support HTML5 video.</span><br><span class="line">        <span class="tag">&lt;/<span class="name">video</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;https://cdn.bootcss.com/flv.js/1.5.0/flv.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">	//下载 flv.js</span><br><span class="line">    </span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span>&gt;</span></span><br><span class="line">         if (flvjs.isSupported()) &#123;</span><br><span class="line">            startVideo()</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line"><span class="javascript">        <span class="function"><span class="keyword">function</span> <span class="title">startVideo</span>(<span class="params"></span>)</span>&#123;</span></span><br><span class="line"><span class="javascript">            <span class="keyword">var</span> videoElement = <span class="built_in">document</span>.getElementById(<span class="string">&#x27;videoElement&#x27;</span>);</span></span><br><span class="line"><span class="javascript">            <span class="keyword">var</span> flvPlayer = flvjs.createPlayer(&#123;</span></span><br><span class="line"><span class="javascript">                type: <span class="string">&#x27;flv&#x27;</span>,</span></span><br><span class="line"><span class="javascript">                isLive: <span class="literal">true</span>,</span></span><br><span class="line"><span class="javascript">                hasAudio: <span class="literal">true</span>,</span></span><br><span class="line"><span class="javascript">                hasVideo: <span class="literal">true</span>,</span></span><br><span class="line"><span class="javascript">                enableStashBuffer: <span class="literal">true</span>,</span></span><br><span class="line"><span class="javascript">                url: <span class="string">&#x27;http://192.168.1.5/test?app=live&amp;stream=wei&#x27;</span><span class="comment">//本地流的地址</span></span></span><br><span class="line">            &#125;);</span><br><span class="line">            flvPlayer.attachMediaElement(videoElement);</span><br><span class="line">            flvPlayer.load();</span><br><span class="line">            flvPlayer.play();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line"><span class="javascript">        videoElement.addEventListener(<span class="string">&#x27;click&#x27;</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span></span><br><span class="line"><span class="javascript">            alert( <span class="string">&#x27;是否支持点播视频：&#x27;</span> + flvjs.getFeatureList().mseFlvPlayback + <span class="string">&#x27; 是否支持httpflv直播流：&#x27;</span> + flvjs.getFeatureList().mseLiveFlvPlayback )</span></span><br><span class="line">        &#125;)</span><br><span class="line"></span><br><span class="line"><span class="javascript">        <span class="function"><span class="keyword">function</span> <span class="title">destoryVideo</span>(<span class="params"></span>)</span>&#123;</span></span><br><span class="line">            flvPlayer.pause();</span><br><span class="line">            flvPlayer.unload();</span><br><span class="line">            flvPlayer.detachMediaElement();</span><br><span class="line">            flvPlayer.destroy();</span><br><span class="line"><span class="javascript">            flvPlayer = <span class="literal">null</span>;</span></span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line"><span class="javascript">        <span class="function"><span class="keyword">function</span> <span class="title">reloadVideo</span>(<span class="params"></span>)</span>&#123;</span></span><br><span class="line">            destoryVideo()</span><br><span class="line">            startVideo()</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">    </span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>

</li>
</ol>
<h3 id="3-3-3-效果展示"><a href="#3-3-3-效果展示" class="headerlink" title="3.3.3 效果展示"></a>3.3.3 效果展示</h3><iframe src="http://player.bilibili.com/player.html?aid=292280366&bvid=BV1Uf4y1V7QV&cid=387263517&page=1" scrolling="no" border="0" width="800px" height="600px" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>

<h2 id="3-4-实验4-架设内网透传并通过4G网络拉流"><a href="#3-4-实验4-架设内网透传并通过4G网络拉流" class="headerlink" title="3.4 实验4 架设内网透传并通过4G网络拉流"></a>3.4 实验4 架设内网透传并通过4G网络拉流</h2><h3 id="3-4-1-假设一下内网穿透"><a href="#3-4-1-假设一下内网穿透" class="headerlink" title="3.4.1 假设一下内网穿透"></a>3.4.1 假设一下内网穿透</h3><p>配置一下网关和花生壳<br>   <img src="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108120006569.png"></p>
<p>不挂花生壳的话要配 NAT表 (前提是网关的ip 是公网ip)<br><img src="https://moses-yu.oss-cn-shenzhen.aliyuncs.com/%E5%9B%BE%E5%BA%8A/202108121548864.png"></p>
<h3 id="3-4-2-推流"><a href="#3-4-2-推流" class="headerlink" title="3.4.2 推流"></a>3.4.2 推流</h3><p> 同3.2.1 这里换了个视频</p>
<h3 id="3-4-3-拉流"><a href="#3-4-3-拉流" class="headerlink" title="3.4.3 拉流"></a>3.4.3 拉流</h3><p> 手机连接4G 公网<br>VLC播放器中点击“媒体”-&gt;“打开网络串流”，输入：<a target="_blank" rel="noopener" href="http://l4t2194987.zicp.vip/test?app=live&amp;stream=wei">http://l4t2194987.zicp.vip/test?app=live&amp;stream=wei</a><br>，就可以播放了</p>
<h3 id="3-4-4-效果演示"><a href="#3-4-4-效果演示" class="headerlink" title="3.4.4 效果演示"></a>3.4.4 效果演示</h3><iframe src="http://player.bilibili.com/player.html?aid=762270340&bvid=BV1t64y1s7ho&cid=387266301&page=1" scrolling="no" border="0" width="800px" height="600px" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>

<h2 id="4-FFmpeg-代码分析"><a href="#4-FFmpeg-代码分析" class="headerlink" title="4 FFmpeg 代码分析"></a>4 FFmpeg 代码分析</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br><span class="line">451</span><br><span class="line">452</span><br><span class="line">453</span><br><span class="line">454</span><br><span class="line">455</span><br><span class="line">456</span><br><span class="line">457</span><br><span class="line">458</span><br><span class="line">459</span><br><span class="line">460</span><br><span class="line">461</span><br><span class="line">462</span><br><span class="line">463</span><br><span class="line">464</span><br><span class="line">465</span><br><span class="line">466</span><br><span class="line">467</span><br><span class="line">468</span><br><span class="line">469</span><br><span class="line">470</span><br><span class="line">471</span><br><span class="line">472</span><br><span class="line">473</span><br><span class="line">474</span><br><span class="line">475</span><br><span class="line">476</span><br><span class="line">477</span><br><span class="line">478</span><br><span class="line">479</span><br><span class="line">480</span><br><span class="line">481</span><br><span class="line">482</span><br><span class="line">483</span><br><span class="line">484</span><br><span class="line">485</span><br><span class="line">486</span><br><span class="line">487</span><br><span class="line">488</span><br><span class="line">489</span><br><span class="line">490</span><br><span class="line">491</span><br><span class="line">492</span><br><span class="line">493</span><br><span class="line">494</span><br><span class="line">495</span><br><span class="line">496</span><br><span class="line">497</span><br><span class="line">498</span><br><span class="line">499</span><br><span class="line">500</span><br><span class="line">501</span><br><span class="line">502</span><br><span class="line">503</span><br><span class="line">504</span><br><span class="line">505</span><br><span class="line">506</span><br><span class="line">507</span><br><span class="line">508</span><br><span class="line">509</span><br><span class="line">510</span><br><span class="line">511</span><br><span class="line">512</span><br><span class="line">513</span><br><span class="line">514</span><br><span class="line">515</span><br><span class="line">516</span><br><span class="line">517</span><br><span class="line">518</span><br><span class="line">519</span><br><span class="line">520</span><br><span class="line">521</span><br><span class="line">522</span><br><span class="line">523</span><br><span class="line">524</span><br><span class="line">525</span><br><span class="line">526</span><br><span class="line">527</span><br><span class="line">528</span><br><span class="line">529</span><br><span class="line">530</span><br><span class="line">531</span><br><span class="line">532</span><br><span class="line">533</span><br><span class="line">534</span><br><span class="line">535</span><br><span class="line">536</span><br><span class="line">537</span><br><span class="line">538</span><br><span class="line">539</span><br><span class="line">540</span><br><span class="line">541</span><br><span class="line">542</span><br><span class="line">543</span><br><span class="line">544</span><br><span class="line">545</span><br><span class="line">546</span><br><span class="line">547</span><br><span class="line">548</span><br><span class="line">549</span><br><span class="line">550</span><br><span class="line">551</span><br><span class="line">552</span><br><span class="line">553</span><br><span class="line">554</span><br><span class="line">555</span><br><span class="line">556</span><br><span class="line">557</span><br><span class="line">558</span><br><span class="line">559</span><br><span class="line">560</span><br><span class="line">561</span><br><span class="line">562</span><br><span class="line">563</span><br><span class="line">564</span><br><span class="line">565</span><br><span class="line">566</span><br><span class="line">567</span><br><span class="line">568</span><br><span class="line">569</span><br><span class="line">570</span><br><span class="line">571</span><br><span class="line">572</span><br><span class="line">573</span><br><span class="line">574</span><br><span class="line">575</span><br><span class="line">576</span><br><span class="line">577</span><br><span class="line">578</span><br><span class="line">579</span><br><span class="line">580</span><br><span class="line">581</span><br><span class="line">582</span><br><span class="line">583</span><br><span class="line">584</span><br><span class="line">585</span><br><span class="line">586</span><br><span class="line">587</span><br><span class="line">588</span><br><span class="line">589</span><br><span class="line">590</span><br><span class="line">591</span><br><span class="line">592</span><br><span class="line">593</span><br><span class="line">594</span><br><span class="line">595</span><br><span class="line">596</span><br><span class="line">597</span><br><span class="line">598</span><br><span class="line">599</span><br><span class="line">600</span><br><span class="line">601</span><br><span class="line">602</span><br><span class="line">603</span><br><span class="line">604</span><br><span class="line">605</span><br><span class="line">606</span><br><span class="line">607</span><br><span class="line">608</span><br><span class="line">609</span><br><span class="line">610</span><br><span class="line">611</span><br><span class="line">612</span><br><span class="line">613</span><br><span class="line">614</span><br><span class="line">615</span><br><span class="line">616</span><br><span class="line">617</span><br><span class="line">618</span><br><span class="line">619</span><br><span class="line">620</span><br><span class="line">621</span><br><span class="line">622</span><br><span class="line">623</span><br><span class="line">624</span><br><span class="line">625</span><br><span class="line">626</span><br><span class="line">627</span><br><span class="line">628</span><br><span class="line">629</span><br><span class="line">630</span><br><span class="line">631</span><br><span class="line">632</span><br><span class="line">633</span><br><span class="line">634</span><br><span class="line">635</span><br><span class="line">636</span><br><span class="line">637</span><br><span class="line">638</span><br><span class="line">639</span><br><span class="line">640</span><br><span class="line">641</span><br><span class="line">642</span><br><span class="line">643</span><br><span class="line">644</span><br><span class="line">645</span><br><span class="line">646</span><br><span class="line">647</span><br><span class="line">648</span><br><span class="line">649</span><br><span class="line">650</span><br><span class="line">651</span><br><span class="line">652</span><br><span class="line">653</span><br><span class="line">654</span><br><span class="line">655</span><br><span class="line">656</span><br><span class="line">657</span><br><span class="line">658</span><br><span class="line">659</span><br><span class="line">660</span><br><span class="line">661</span><br><span class="line">662</span><br><span class="line">663</span><br><span class="line">664</span><br><span class="line">665</span><br><span class="line">666</span><br><span class="line">667</span><br><span class="line">668</span><br><span class="line">669</span><br><span class="line">670</span><br><span class="line">671</span><br><span class="line">672</span><br><span class="line">673</span><br><span class="line">674</span><br><span class="line">675</span><br><span class="line">676</span><br><span class="line">677</span><br><span class="line">678</span><br><span class="line">679</span><br><span class="line">680</span><br><span class="line">681</span><br><span class="line">682</span><br><span class="line">683</span><br><span class="line">684</span><br><span class="line">685</span><br><span class="line">686</span><br><span class="line">687</span><br><span class="line">688</span><br><span class="line">689</span><br><span class="line">690</span><br><span class="line">691</span><br><span class="line">692</span><br><span class="line">693</span><br><span class="line">694</span><br><span class="line">695</span><br><span class="line">696</span><br><span class="line">697</span><br><span class="line">698</span><br><span class="line">699</span><br><span class="line">700</span><br><span class="line">701</span><br><span class="line">702</span><br><span class="line">703</span><br><span class="line">704</span><br><span class="line">705</span><br><span class="line">706</span><br><span class="line">707</span><br><span class="line">708</span><br><span class="line">709</span><br><span class="line">710</span><br><span class="line">711</span><br><span class="line">712</span><br><span class="line">713</span><br><span class="line">714</span><br><span class="line">715</span><br><span class="line">716</span><br><span class="line">717</span><br><span class="line">718</span><br><span class="line">719</span><br><span class="line">720</span><br><span class="line">721</span><br><span class="line">722</span><br><span class="line">723</span><br><span class="line">724</span><br><span class="line">725</span><br><span class="line">726</span><br><span class="line">727</span><br><span class="line">728</span><br><span class="line">729</span><br><span class="line">730</span><br><span class="line">731</span><br><span class="line">732</span><br><span class="line">733</span><br><span class="line">734</span><br><span class="line">735</span><br><span class="line">736</span><br><span class="line">737</span><br><span class="line">738</span><br><span class="line">739</span><br><span class="line">740</span><br><span class="line">741</span><br><span class="line">742</span><br><span class="line">743</span><br><span class="line">744</span><br><span class="line">745</span><br><span class="line">746</span><br><span class="line">747</span><br><span class="line">748</span><br><span class="line">749</span><br><span class="line">750</span><br><span class="line">751</span><br><span class="line">752</span><br><span class="line">753</span><br><span class="line">754</span><br><span class="line">755</span><br><span class="line">756</span><br><span class="line">757</span><br><span class="line">758</span><br><span class="line">759</span><br><span class="line">760</span><br><span class="line">761</span><br><span class="line">762</span><br><span class="line">763</span><br><span class="line">764</span><br><span class="line">765</span><br><span class="line">766</span><br><span class="line">767</span><br><span class="line">768</span><br><span class="line">769</span><br><span class="line">770</span><br><span class="line">771</span><br><span class="line">772</span><br><span class="line">773</span><br><span class="line">774</span><br><span class="line">775</span><br><span class="line">776</span><br><span class="line">777</span><br><span class="line">778</span><br><span class="line">779</span><br><span class="line">780</span><br><span class="line">781</span><br><span class="line">782</span><br><span class="line">783</span><br><span class="line">784</span><br><span class="line">785</span><br><span class="line">786</span><br><span class="line">787</span><br><span class="line">788</span><br><span class="line">789</span><br><span class="line">790</span><br><span class="line">791</span><br><span class="line">792</span><br><span class="line">793</span><br><span class="line">794</span><br><span class="line">795</span><br><span class="line">796</span><br><span class="line">797</span><br><span class="line">798</span><br><span class="line">799</span><br><span class="line">800</span><br><span class="line">801</span><br><span class="line">802</span><br><span class="line">803</span><br><span class="line">804</span><br><span class="line">805</span><br><span class="line">806</span><br><span class="line">807</span><br><span class="line">808</span><br><span class="line">809</span><br><span class="line">810</span><br><span class="line">811</span><br><span class="line">812</span><br><span class="line">813</span><br><span class="line">814</span><br><span class="line">815</span><br><span class="line">816</span><br><span class="line">817</span><br><span class="line">818</span><br><span class="line">819</span><br><span class="line">820</span><br><span class="line">821</span><br><span class="line">822</span><br><span class="line">823</span><br><span class="line">824</span><br><span class="line">825</span><br><span class="line">826</span><br><span class="line">827</span><br><span class="line">828</span><br><span class="line">829</span><br><span class="line">830</span><br><span class="line">831</span><br><span class="line">832</span><br><span class="line">833</span><br><span class="line">834</span><br><span class="line">835</span><br><span class="line">836</span><br><span class="line">837</span><br><span class="line">838</span><br><span class="line">839</span><br><span class="line">840</span><br><span class="line">841</span><br><span class="line">842</span><br><span class="line">843</span><br><span class="line">844</span><br><span class="line">845</span><br><span class="line">846</span><br><span class="line">847</span><br><span class="line">848</span><br><span class="line">849</span><br><span class="line">850</span><br><span class="line">851</span><br><span class="line">852</span><br><span class="line">853</span><br><span class="line">854</span><br><span class="line">855</span><br><span class="line">856</span><br><span class="line">857</span><br><span class="line">858</span><br><span class="line">859</span><br><span class="line">860</span><br><span class="line">861</span><br><span class="line">862</span><br><span class="line">863</span><br><span class="line">864</span><br><span class="line">865</span><br><span class="line">866</span><br><span class="line">867</span><br><span class="line">868</span><br><span class="line">869</span><br><span class="line">870</span><br><span class="line">871</span><br><span class="line">872</span><br><span class="line">873</span><br><span class="line">874</span><br><span class="line">875</span><br><span class="line">876</span><br><span class="line">877</span><br><span class="line">878</span><br><span class="line">879</span><br><span class="line">880</span><br><span class="line">881</span><br><span class="line">882</span><br><span class="line">883</span><br><span class="line">884</span><br><span class="line">885</span><br><span class="line">886</span><br><span class="line">887</span><br><span class="line">888</span><br><span class="line">889</span><br><span class="line">890</span><br><span class="line">891</span><br><span class="line">892</span><br><span class="line">893</span><br><span class="line">894</span><br><span class="line">895</span><br><span class="line">896</span><br><span class="line">897</span><br><span class="line">898</span><br><span class="line">899</span><br><span class="line">900</span><br><span class="line">901</span><br><span class="line">902</span><br><span class="line">903</span><br><span class="line">904</span><br><span class="line">905</span><br><span class="line">906</span><br><span class="line">907</span><br><span class="line">908</span><br><span class="line">909</span><br><span class="line">910</span><br><span class="line">911</span><br><span class="line">912</span><br><span class="line">913</span><br><span class="line">914</span><br><span class="line">915</span><br><span class="line">916</span><br><span class="line">917</span><br><span class="line">918</span><br><span class="line">919</span><br><span class="line">920</span><br><span class="line">921</span><br><span class="line">922</span><br><span class="line">923</span><br><span class="line">924</span><br><span class="line">925</span><br><span class="line">926</span><br><span class="line">927</span><br><span class="line">928</span><br><span class="line">929</span><br><span class="line">930</span><br><span class="line">931</span><br><span class="line">932</span><br><span class="line">933</span><br><span class="line">934</span><br><span class="line">935</span><br><span class="line">936</span><br><span class="line">937</span><br><span class="line">938</span><br><span class="line">939</span><br><span class="line">940</span><br><span class="line">941</span><br><span class="line">942</span><br><span class="line">943</span><br><span class="line">944</span><br><span class="line">945</span><br><span class="line">946</span><br><span class="line">947</span><br><span class="line">948</span><br><span class="line">949</span><br><span class="line">950</span><br><span class="line">951</span><br><span class="line">952</span><br><span class="line">953</span><br><span class="line">954</span><br><span class="line">955</span><br><span class="line">956</span><br><span class="line">957</span><br><span class="line">958</span><br><span class="line">959</span><br><span class="line">960</span><br><span class="line">961</span><br><span class="line">962</span><br><span class="line">963</span><br><span class="line">964</span><br><span class="line">965</span><br><span class="line">966</span><br><span class="line">967</span><br><span class="line">968</span><br><span class="line">969</span><br><span class="line">970</span><br><span class="line">971</span><br><span class="line">972</span><br><span class="line">973</span><br><span class="line">974</span><br><span class="line">975</span><br><span class="line">976</span><br><span class="line">977</span><br><span class="line">978</span><br><span class="line">979</span><br><span class="line">980</span><br><span class="line">981</span><br><span class="line">982</span><br><span class="line">983</span><br><span class="line">984</span><br><span class="line">985</span><br><span class="line">986</span><br><span class="line">987</span><br><span class="line">988</span><br><span class="line">989</span><br><span class="line">990</span><br><span class="line">991</span><br><span class="line">992</span><br><span class="line">993</span><br><span class="line">994</span><br><span class="line">995</span><br><span class="line">996</span><br><span class="line">997</span><br><span class="line">998</span><br><span class="line">999</span><br><span class="line">1000</span><br><span class="line">1001</span><br><span class="line">1002</span><br><span class="line">1003</span><br><span class="line">1004</span><br><span class="line">1005</span><br><span class="line">1006</span><br><span class="line">1007</span><br><span class="line">1008</span><br><span class="line">1009</span><br><span class="line">1010</span><br><span class="line">1011</span><br><span class="line">1012</span><br><span class="line">1013</span><br><span class="line">1014</span><br><span class="line">1015</span><br><span class="line">1016</span><br><span class="line">1017</span><br><span class="line">1018</span><br><span class="line">1019</span><br><span class="line">1020</span><br><span class="line">1021</span><br><span class="line">1022</span><br><span class="line">1023</span><br><span class="line">1024</span><br><span class="line">1025</span><br><span class="line">1026</span><br><span class="line">1027</span><br><span class="line">1028</span><br><span class="line">1029</span><br><span class="line">1030</span><br><span class="line">1031</span><br><span class="line">1032</span><br><span class="line">1033</span><br><span class="line">1034</span><br><span class="line">1035</span><br><span class="line">1036</span><br><span class="line">1037</span><br><span class="line">1038</span><br><span class="line">1039</span><br><span class="line">1040</span><br><span class="line">1041</span><br><span class="line">1042</span><br><span class="line">1043</span><br><span class="line">1044</span><br><span class="line">1045</span><br><span class="line">1046</span><br><span class="line">1047</span><br><span class="line">1048</span><br><span class="line">1049</span><br><span class="line">1050</span><br><span class="line">1051</span><br><span class="line">1052</span><br><span class="line">1053</span><br><span class="line">1054</span><br><span class="line">1055</span><br><span class="line">1056</span><br><span class="line">1057</span><br><span class="line">1058</span><br><span class="line">1059</span><br><span class="line">1060</span><br><span class="line">1061</span><br><span class="line">1062</span><br><span class="line">1063</span><br><span class="line">1064</span><br><span class="line">1065</span><br><span class="line">1066</span><br><span class="line">1067</span><br><span class="line">1068</span><br><span class="line">1069</span><br><span class="line">1070</span><br><span class="line">1071</span><br><span class="line">1072</span><br><span class="line">1073</span><br><span class="line">1074</span><br><span class="line">1075</span><br><span class="line">1076</span><br><span class="line">1077</span><br><span class="line">1078</span><br><span class="line">1079</span><br><span class="line">1080</span><br><span class="line">1081</span><br><span class="line">1082</span><br><span class="line">1083</span><br><span class="line">1084</span><br><span class="line">1085</span><br><span class="line">1086</span><br><span class="line">1087</span><br><span class="line">1088</span><br><span class="line">1089</span><br><span class="line">1090</span><br><span class="line">1091</span><br><span class="line">1092</span><br><span class="line">1093</span><br><span class="line">1094</span><br><span class="line">1095</span><br><span class="line">1096</span><br><span class="line">1097</span><br><span class="line">1098</span><br><span class="line">1099</span><br><span class="line">1100</span><br><span class="line">1101</span><br><span class="line">1102</span><br><span class="line">1103</span><br><span class="line">1104</span><br><span class="line">1105</span><br><span class="line">1106</span><br><span class="line">1107</span><br><span class="line">1108</span><br><span class="line">1109</span><br><span class="line">1110</span><br><span class="line">1111</span><br><span class="line">1112</span><br><span class="line">1113</span><br><span class="line">1114</span><br><span class="line">1115</span><br><span class="line">1116</span><br><span class="line">1117</span><br><span class="line">1118</span><br><span class="line">1119</span><br><span class="line">1120</span><br><span class="line">1121</span><br><span class="line">1122</span><br><span class="line">1123</span><br><span class="line">1124</span><br><span class="line">1125</span><br><span class="line">1126</span><br><span class="line">1127</span><br><span class="line">1128</span><br><span class="line">1129</span><br><span class="line">1130</span><br><span class="line">1131</span><br><span class="line">1132</span><br><span class="line">1133</span><br><span class="line">1134</span><br><span class="line">1135</span><br><span class="line">1136</span><br><span class="line">1137</span><br><span class="line">1138</span><br><span class="line">1139</span><br><span class="line">1140</span><br><span class="line">1141</span><br><span class="line">1142</span><br><span class="line">1143</span><br><span class="line">1144</span><br><span class="line">1145</span><br><span class="line">1146</span><br><span class="line">1147</span><br><span class="line">1148</span><br><span class="line">1149</span><br><span class="line">1150</span><br><span class="line">1151</span><br><span class="line">1152</span><br><span class="line">1153</span><br><span class="line">1154</span><br><span class="line">1155</span><br><span class="line">1156</span><br><span class="line">1157</span><br><span class="line">1158</span><br><span class="line">1159</span><br><span class="line">1160</span><br><span class="line">1161</span><br><span class="line">1162</span><br><span class="line">1163</span><br><span class="line">1164</span><br><span class="line">1165</span><br><span class="line">1166</span><br><span class="line">1167</span><br><span class="line">1168</span><br><span class="line">1169</span><br><span class="line">1170</span><br><span class="line">1171</span><br><span class="line">1172</span><br><span class="line">1173</span><br><span class="line">1174</span><br><span class="line">1175</span><br><span class="line">1176</span><br><span class="line">1177</span><br><span class="line">1178</span><br><span class="line">1179</span><br><span class="line">1180</span><br><span class="line">1181</span><br><span class="line">1182</span><br><span class="line">1183</span><br><span class="line">1184</span><br><span class="line">1185</span><br><span class="line">1186</span><br><span class="line">1187</span><br><span class="line">1188</span><br><span class="line">1189</span><br><span class="line">1190</span><br><span class="line">1191</span><br><span class="line">1192</span><br><span class="line">1193</span><br><span class="line">1194</span><br><span class="line">1195</span><br><span class="line">1196</span><br><span class="line">1197</span><br><span class="line">1198</span><br><span class="line">1199</span><br><span class="line">1200</span><br><span class="line">1201</span><br><span class="line">1202</span><br><span class="line">1203</span><br><span class="line">1204</span><br><span class="line">1205</span><br><span class="line">1206</span><br><span class="line">1207</span><br><span class="line">1208</span><br><span class="line">1209</span><br><span class="line">1210</span><br><span class="line">1211</span><br><span class="line">1212</span><br><span class="line">1213</span><br><span class="line">1214</span><br><span class="line">1215</span><br><span class="line">1216</span><br><span class="line">1217</span><br><span class="line">1218</span><br><span class="line">1219</span><br><span class="line">1220</span><br><span class="line">1221</span><br><span class="line">1222</span><br><span class="line">1223</span><br><span class="line">1224</span><br><span class="line">1225</span><br><span class="line">1226</span><br><span class="line">1227</span><br><span class="line">1228</span><br><span class="line">1229</span><br><span class="line">1230</span><br><span class="line">1231</span><br><span class="line">1232</span><br><span class="line">1233</span><br><span class="line">1234</span><br><span class="line">1235</span><br><span class="line">1236</span><br><span class="line">1237</span><br><span class="line">1238</span><br><span class="line">1239</span><br><span class="line">1240</span><br><span class="line">1241</span><br><span class="line">1242</span><br><span class="line">1243</span><br><span class="line">1244</span><br><span class="line">1245</span><br><span class="line">1246</span><br><span class="line">1247</span><br><span class="line">1248</span><br><span class="line">1249</span><br><span class="line">1250</span><br><span class="line">1251</span><br><span class="line">1252</span><br><span class="line">1253</span><br><span class="line">1254</span><br><span class="line">1255</span><br><span class="line">1256</span><br><span class="line">1257</span><br><span class="line">1258</span><br><span class="line">1259</span><br><span class="line">1260</span><br><span class="line">1261</span><br><span class="line">1262</span><br><span class="line">1263</span><br><span class="line">1264</span><br><span class="line">1265</span><br><span class="line">1266</span><br><span class="line">1267</span><br><span class="line">1268</span><br><span class="line">1269</span><br><span class="line">1270</span><br><span class="line">1271</span><br><span class="line">1272</span><br><span class="line">1273</span><br><span class="line">1274</span><br><span class="line">1275</span><br><span class="line">1276</span><br><span class="line">1277</span><br><span class="line">1278</span><br><span class="line">1279</span><br><span class="line">1280</span><br><span class="line">1281</span><br><span class="line">1282</span><br><span class="line">1283</span><br><span class="line">1284</span><br><span class="line">1285</span><br><span class="line">1286</span><br><span class="line">1287</span><br><span class="line">1288</span><br><span class="line">1289</span><br><span class="line">1290</span><br><span class="line">1291</span><br><span class="line">1292</span><br><span class="line">1293</span><br><span class="line">1294</span><br><span class="line">1295</span><br><span class="line">1296</span><br><span class="line">1297</span><br><span class="line">1298</span><br><span class="line">1299</span><br><span class="line">1300</span><br><span class="line">1301</span><br><span class="line">1302</span><br><span class="line">1303</span><br><span class="line">1304</span><br><span class="line">1305</span><br><span class="line">1306</span><br><span class="line">1307</span><br><span class="line">1308</span><br><span class="line">1309</span><br><span class="line">1310</span><br><span class="line">1311</span><br><span class="line">1312</span><br><span class="line">1313</span><br><span class="line">1314</span><br><span class="line">1315</span><br><span class="line">1316</span><br><span class="line">1317</span><br><span class="line">1318</span><br><span class="line">1319</span><br><span class="line">1320</span><br><span class="line">1321</span><br><span class="line">1322</span><br><span class="line">1323</span><br><span class="line">1324</span><br><span class="line">1325</span><br><span class="line">1326</span><br><span class="line">1327</span><br><span class="line">1328</span><br><span class="line">1329</span><br><span class="line">1330</span><br><span class="line">1331</span><br><span class="line">1332</span><br><span class="line">1333</span><br><span class="line">1334</span><br><span class="line">1335</span><br><span class="line">1336</span><br><span class="line">1337</span><br><span class="line">1338</span><br><span class="line">1339</span><br><span class="line">1340</span><br><span class="line">1341</span><br><span class="line">1342</span><br><span class="line">1343</span><br><span class="line">1344</span><br><span class="line">1345</span><br><span class="line">1346</span><br><span class="line">1347</span><br><span class="line">1348</span><br><span class="line">1349</span><br><span class="line">1350</span><br><span class="line">1351</span><br><span class="line">1352</span><br><span class="line">1353</span><br><span class="line">1354</span><br><span class="line">1355</span><br><span class="line">1356</span><br><span class="line">1357</span><br><span class="line">1358</span><br><span class="line">1359</span><br><span class="line">1360</span><br><span class="line">1361</span><br><span class="line">1362</span><br><span class="line">1363</span><br><span class="line">1364</span><br><span class="line">1365</span><br><span class="line">1366</span><br><span class="line">1367</span><br><span class="line">1368</span><br><span class="line">1369</span><br><span class="line">1370</span><br><span class="line">1371</span><br><span class="line">1372</span><br><span class="line">1373</span><br><span class="line">1374</span><br><span class="line">1375</span><br><span class="line">1376</span><br><span class="line">1377</span><br><span class="line">1378</span><br><span class="line">1379</span><br><span class="line">1380</span><br><span class="line">1381</span><br><span class="line">1382</span><br><span class="line">1383</span><br><span class="line">1384</span><br><span class="line">1385</span><br><span class="line">1386</span><br><span class="line">1387</span><br><span class="line">1388</span><br><span class="line">1389</span><br><span class="line">1390</span><br><span class="line">1391</span><br><span class="line">1392</span><br><span class="line">1393</span><br><span class="line">1394</span><br><span class="line">1395</span><br><span class="line">1396</span><br><span class="line">1397</span><br><span class="line">1398</span><br><span class="line">1399</span><br><span class="line">1400</span><br><span class="line">1401</span><br><span class="line">1402</span><br><span class="line">1403</span><br><span class="line">1404</span><br><span class="line">1405</span><br><span class="line">1406</span><br><span class="line">1407</span><br><span class="line">1408</span><br><span class="line">1409</span><br><span class="line">1410</span><br><span class="line">1411</span><br><span class="line">1412</span><br><span class="line">1413</span><br><span class="line">1414</span><br><span class="line">1415</span><br><span class="line">1416</span><br><span class="line">1417</span><br><span class="line">1418</span><br><span class="line">1419</span><br><span class="line">1420</span><br><span class="line">1421</span><br><span class="line">1422</span><br><span class="line">1423</span><br><span class="line">1424</span><br><span class="line">1425</span><br><span class="line">1426</span><br><span class="line">1427</span><br><span class="line">1428</span><br><span class="line">1429</span><br><span class="line">1430</span><br><span class="line">1431</span><br><span class="line">1432</span><br><span class="line">1433</span><br><span class="line">1434</span><br><span class="line">1435</span><br><span class="line">1436</span><br><span class="line">1437</span><br><span class="line">1438</span><br><span class="line">1439</span><br><span class="line">1440</span><br><span class="line">1441</span><br><span class="line">1442</span><br><span class="line">1443</span><br><span class="line">1444</span><br><span class="line">1445</span><br><span class="line">1446</span><br><span class="line">1447</span><br><span class="line">1448</span><br><span class="line">1449</span><br><span class="line">1450</span><br><span class="line">1451</span><br><span class="line">1452</span><br><span class="line">1453</span><br><span class="line">1454</span><br><span class="line">1455</span><br><span class="line">1456</span><br><span class="line">1457</span><br><span class="line">1458</span><br><span class="line">1459</span><br><span class="line">1460</span><br><span class="line">1461</span><br><span class="line">1462</span><br><span class="line">1463</span><br><span class="line">1464</span><br><span class="line">1465</span><br><span class="line">1466</span><br><span class="line">1467</span><br><span class="line">1468</span><br><span class="line">1469</span><br><span class="line">1470</span><br><span class="line">1471</span><br><span class="line">1472</span><br><span class="line">1473</span><br><span class="line">1474</span><br><span class="line">1475</span><br><span class="line">1476</span><br><span class="line">1477</span><br><span class="line">1478</span><br><span class="line">1479</span><br><span class="line">1480</span><br><span class="line">1481</span><br><span class="line">1482</span><br><span class="line">1483</span><br><span class="line">1484</span><br><span class="line">1485</span><br><span class="line">1486</span><br><span class="line">1487</span><br><span class="line">1488</span><br><span class="line">1489</span><br><span class="line">1490</span><br><span class="line">1491</span><br><span class="line">1492</span><br><span class="line">1493</span><br><span class="line">1494</span><br><span class="line">1495</span><br><span class="line">1496</span><br><span class="line">1497</span><br><span class="line">1498</span><br><span class="line">1499</span><br><span class="line">1500</span><br><span class="line">1501</span><br><span class="line">1502</span><br><span class="line">1503</span><br><span class="line">1504</span><br><span class="line">1505</span><br><span class="line">1506</span><br><span class="line">1507</span><br><span class="line">1508</span><br><span class="line">1509</span><br><span class="line">1510</span><br><span class="line">1511</span><br><span class="line">1512</span><br><span class="line">1513</span><br><span class="line">1514</span><br><span class="line">1515</span><br><span class="line">1516</span><br><span class="line">1517</span><br><span class="line">1518</span><br><span class="line">1519</span><br><span class="line">1520</span><br><span class="line">1521</span><br><span class="line">1522</span><br><span class="line">1523</span><br><span class="line">1524</span><br><span class="line">1525</span><br><span class="line">1526</span><br><span class="line">1527</span><br><span class="line">1528</span><br><span class="line">1529</span><br><span class="line">1530</span><br><span class="line">1531</span><br><span class="line">1532</span><br><span class="line">1533</span><br><span class="line">1534</span><br><span class="line">1535</span><br><span class="line">1536</span><br><span class="line">1537</span><br><span class="line">1538</span><br><span class="line">1539</span><br><span class="line">1540</span><br><span class="line">1541</span><br><span class="line">1542</span><br><span class="line">1543</span><br><span class="line">1544</span><br><span class="line">1545</span><br><span class="line">1546</span><br><span class="line">1547</span><br><span class="line">1548</span><br><span class="line">1549</span><br><span class="line">1550</span><br><span class="line">1551</span><br><span class="line">1552</span><br><span class="line">1553</span><br><span class="line">1554</span><br><span class="line">1555</span><br><span class="line">1556</span><br><span class="line">1557</span><br><span class="line">1558</span><br><span class="line">1559</span><br><span class="line">1560</span><br><span class="line">1561</span><br><span class="line">1562</span><br><span class="line">1563</span><br><span class="line">1564</span><br><span class="line">1565</span><br><span class="line">1566</span><br><span class="line">1567</span><br><span class="line">1568</span><br><span class="line">1569</span><br><span class="line">1570</span><br><span class="line">1571</span><br><span class="line">1572</span><br><span class="line">1573</span><br><span class="line">1574</span><br><span class="line">1575</span><br><span class="line">1576</span><br><span class="line">1577</span><br><span class="line">1578</span><br><span class="line">1579</span><br><span class="line">1580</span><br><span class="line">1581</span><br><span class="line">1582</span><br><span class="line">1583</span><br><span class="line">1584</span><br><span class="line">1585</span><br><span class="line">1586</span><br><span class="line">1587</span><br><span class="line">1588</span><br><span class="line">1589</span><br><span class="line">1590</span><br><span class="line">1591</span><br><span class="line">1592</span><br><span class="line">1593</span><br><span class="line">1594</span><br><span class="line">1595</span><br><span class="line">1596</span><br><span class="line">1597</span><br><span class="line">1598</span><br><span class="line">1599</span><br><span class="line">1600</span><br><span class="line">1601</span><br><span class="line">1602</span><br><span class="line">1603</span><br><span class="line">1604</span><br><span class="line">1605</span><br><span class="line">1606</span><br><span class="line">1607</span><br><span class="line">1608</span><br><span class="line">1609</span><br><span class="line">1610</span><br><span class="line">1611</span><br><span class="line">1612</span><br><span class="line">1613</span><br><span class="line">1614</span><br><span class="line">1615</span><br><span class="line">1616</span><br><span class="line">1617</span><br><span class="line">1618</span><br><span class="line">1619</span><br><span class="line">1620</span><br><span class="line">1621</span><br><span class="line">1622</span><br><span class="line">1623</span><br><span class="line">1624</span><br><span class="line">1625</span><br><span class="line">1626</span><br><span class="line">1627</span><br><span class="line">1628</span><br><span class="line">1629</span><br><span class="line">1630</span><br><span class="line">1631</span><br><span class="line">1632</span><br><span class="line">1633</span><br><span class="line">1634</span><br><span class="line">1635</span><br><span class="line">1636</span><br><span class="line">1637</span><br><span class="line">1638</span><br><span class="line">1639</span><br><span class="line">1640</span><br><span class="line">1641</span><br><span class="line">1642</span><br><span class="line">1643</span><br><span class="line">1644</span><br><span class="line">1645</span><br><span class="line">1646</span><br><span class="line">1647</span><br><span class="line">1648</span><br><span class="line">1649</span><br><span class="line">1650</span><br><span class="line">1651</span><br><span class="line">1652</span><br><span class="line">1653</span><br><span class="line">1654</span><br><span class="line">1655</span><br><span class="line">1656</span><br><span class="line">1657</span><br><span class="line">1658</span><br><span class="line">1659</span><br><span class="line">1660</span><br><span class="line">1661</span><br><span class="line">1662</span><br><span class="line">1663</span><br><span class="line">1664</span><br><span class="line">1665</span><br><span class="line">1666</span><br><span class="line">1667</span><br><span class="line">1668</span><br><span class="line">1669</span><br><span class="line">1670</span><br><span class="line">1671</span><br><span class="line">1672</span><br><span class="line">1673</span><br><span class="line">1674</span><br><span class="line">1675</span><br><span class="line">1676</span><br><span class="line">1677</span><br><span class="line">1678</span><br><span class="line">1679</span><br><span class="line">1680</span><br><span class="line">1681</span><br><span class="line">1682</span><br><span class="line">1683</span><br><span class="line">1684</span><br><span class="line">1685</span><br><span class="line">1686</span><br><span class="line">1687</span><br><span class="line">1688</span><br><span class="line">1689</span><br><span class="line">1690</span><br><span class="line">1691</span><br><span class="line">1692</span><br><span class="line">1693</span><br><span class="line">1694</span><br><span class="line">1695</span><br><span class="line">1696</span><br><span class="line">1697</span><br><span class="line">1698</span><br><span class="line">1699</span><br><span class="line">1700</span><br><span class="line">1701</span><br><span class="line">1702</span><br><span class="line">1703</span><br><span class="line">1704</span><br><span class="line">1705</span><br><span class="line">1706</span><br><span class="line">1707</span><br><span class="line">1708</span><br><span class="line">1709</span><br><span class="line">1710</span><br><span class="line">1711</span><br><span class="line">1712</span><br><span class="line">1713</span><br><span class="line">1714</span><br><span class="line">1715</span><br><span class="line">1716</span><br><span class="line">1717</span><br><span class="line">1718</span><br><span class="line">1719</span><br><span class="line">1720</span><br><span class="line">1721</span><br><span class="line">1722</span><br><span class="line">1723</span><br><span class="line">1724</span><br><span class="line">1725</span><br><span class="line">1726</span><br><span class="line">1727</span><br><span class="line">1728</span><br><span class="line">1729</span><br><span class="line">1730</span><br><span class="line">1731</span><br><span class="line">1732</span><br><span class="line">1733</span><br><span class="line">1734</span><br><span class="line">1735</span><br><span class="line">1736</span><br><span class="line">1737</span><br><span class="line">1738</span><br><span class="line">1739</span><br><span class="line">1740</span><br><span class="line">1741</span><br><span class="line">1742</span><br><span class="line">1743</span><br><span class="line">1744</span><br><span class="line">1745</span><br><span class="line">1746</span><br><span class="line">1747</span><br><span class="line">1748</span><br><span class="line">1749</span><br><span class="line">1750</span><br><span class="line">1751</span><br><span class="line">1752</span><br><span class="line">1753</span><br><span class="line">1754</span><br><span class="line">1755</span><br><span class="line">1756</span><br><span class="line">1757</span><br><span class="line">1758</span><br><span class="line">1759</span><br><span class="line">1760</span><br><span class="line">1761</span><br><span class="line">1762</span><br><span class="line">1763</span><br><span class="line">1764</span><br><span class="line">1765</span><br><span class="line">1766</span><br><span class="line">1767</span><br><span class="line">1768</span><br><span class="line">1769</span><br><span class="line">1770</span><br><span class="line">1771</span><br><span class="line">1772</span><br><span class="line">1773</span><br><span class="line">1774</span><br><span class="line">1775</span><br><span class="line">1776</span><br><span class="line">1777</span><br><span class="line">1778</span><br><span class="line">1779</span><br><span class="line">1780</span><br><span class="line">1781</span><br><span class="line">1782</span><br><span class="line">1783</span><br><span class="line">1784</span><br><span class="line">1785</span><br><span class="line">1786</span><br><span class="line">1787</span><br><span class="line">1788</span><br><span class="line">1789</span><br><span class="line">1790</span><br><span class="line">1791</span><br><span class="line">1792</span><br><span class="line">1793</span><br><span class="line">1794</span><br><span class="line">1795</span><br><span class="line">1796</span><br><span class="line">1797</span><br><span class="line">1798</span><br><span class="line">1799</span><br><span class="line">1800</span><br><span class="line">1801</span><br><span class="line">1802</span><br><span class="line">1803</span><br><span class="line">1804</span><br><span class="line">1805</span><br><span class="line">1806</span><br><span class="line">1807</span><br><span class="line">1808</span><br><span class="line">1809</span><br><span class="line">1810</span><br><span class="line">1811</span><br><span class="line">1812</span><br><span class="line">1813</span><br><span class="line">1814</span><br><span class="line">1815</span><br><span class="line">1816</span><br><span class="line">1817</span><br><span class="line">1818</span><br><span class="line">1819</span><br><span class="line">1820</span><br><span class="line">1821</span><br><span class="line">1822</span><br><span class="line">1823</span><br><span class="line">1824</span><br><span class="line">1825</span><br><span class="line">1826</span><br><span class="line">1827</span><br><span class="line">1828</span><br><span class="line">1829</span><br><span class="line">1830</span><br><span class="line">1831</span><br><span class="line">1832</span><br><span class="line">1833</span><br><span class="line">1834</span><br><span class="line">1835</span><br><span class="line">1836</span><br><span class="line">1837</span><br><span class="line">1838</span><br><span class="line">1839</span><br><span class="line">1840</span><br><span class="line">1841</span><br><span class="line">1842</span><br><span class="line">1843</span><br><span class="line">1844</span><br><span class="line">1845</span><br><span class="line">1846</span><br><span class="line">1847</span><br><span class="line">1848</span><br><span class="line">1849</span><br><span class="line">1850</span><br><span class="line">1851</span><br><span class="line">1852</span><br><span class="line">1853</span><br><span class="line">1854</span><br><span class="line">1855</span><br><span class="line">1856</span><br><span class="line">1857</span><br><span class="line">1858</span><br><span class="line">1859</span><br><span class="line">1860</span><br><span class="line">1861</span><br><span class="line">1862</span><br><span class="line">1863</span><br><span class="line">1864</span><br><span class="line">1865</span><br><span class="line">1866</span><br><span class="line">1867</span><br><span class="line">1868</span><br><span class="line">1869</span><br><span class="line">1870</span><br><span class="line">1871</span><br><span class="line">1872</span><br><span class="line">1873</span><br><span class="line">1874</span><br><span class="line">1875</span><br><span class="line">1876</span><br><span class="line">1877</span><br><span class="line">1878</span><br><span class="line">1879</span><br><span class="line">1880</span><br><span class="line">1881</span><br><span class="line">1882</span><br><span class="line">1883</span><br><span class="line">1884</span><br><span class="line">1885</span><br><span class="line">1886</span><br><span class="line">1887</span><br><span class="line">1888</span><br><span class="line">1889</span><br><span class="line">1890</span><br><span class="line">1891</span><br><span class="line">1892</span><br><span class="line">1893</span><br><span class="line">1894</span><br><span class="line">1895</span><br><span class="line">1896</span><br><span class="line">1897</span><br><span class="line">1898</span><br><span class="line">1899</span><br><span class="line">1900</span><br><span class="line">1901</span><br><span class="line">1902</span><br><span class="line">1903</span><br><span class="line">1904</span><br><span class="line">1905</span><br><span class="line">1906</span><br><span class="line">1907</span><br><span class="line">1908</span><br><span class="line">1909</span><br><span class="line">1910</span><br><span class="line">1911</span><br><span class="line">1912</span><br><span class="line">1913</span><br><span class="line">1914</span><br><span class="line">1915</span><br><span class="line">1916</span><br><span class="line">1917</span><br><span class="line">1918</span><br><span class="line">1919</span><br><span class="line">1920</span><br><span class="line">1921</span><br><span class="line">1922</span><br><span class="line">1923</span><br><span class="line">1924</span><br><span class="line">1925</span><br><span class="line">1926</span><br><span class="line">1927</span><br><span class="line">1928</span><br><span class="line">1929</span><br><span class="line">1930</span><br><span class="line">1931</span><br><span class="line">1932</span><br><span class="line">1933</span><br><span class="line">1934</span><br><span class="line">1935</span><br><span class="line">1936</span><br><span class="line">1937</span><br><span class="line">1938</span><br><span class="line">1939</span><br><span class="line">1940</span><br><span class="line">1941</span><br><span class="line">1942</span><br><span class="line">1943</span><br><span class="line">1944</span><br><span class="line">1945</span><br><span class="line">1946</span><br><span class="line">1947</span><br><span class="line">1948</span><br><span class="line">1949</span><br><span class="line">1950</span><br><span class="line">1951</span><br><span class="line">1952</span><br><span class="line">1953</span><br><span class="line">1954</span><br><span class="line">1955</span><br><span class="line">1956</span><br><span class="line">1957</span><br><span class="line">1958</span><br><span class="line">1959</span><br><span class="line">1960</span><br><span class="line">1961</span><br><span class="line">1962</span><br><span class="line">1963</span><br><span class="line">1964</span><br><span class="line">1965</span><br><span class="line">1966</span><br><span class="line">1967</span><br><span class="line">1968</span><br><span class="line">1969</span><br><span class="line">1970</span><br><span class="line">1971</span><br><span class="line">1972</span><br><span class="line">1973</span><br><span class="line">1974</span><br><span class="line">1975</span><br><span class="line">1976</span><br><span class="line">1977</span><br><span class="line">1978</span><br><span class="line">1979</span><br><span class="line">1980</span><br><span class="line">1981</span><br><span class="line">1982</span><br><span class="line">1983</span><br><span class="line">1984</span><br><span class="line">1985</span><br><span class="line">1986</span><br><span class="line">1987</span><br><span class="line">1988</span><br><span class="line">1989</span><br><span class="line">1990</span><br><span class="line">1991</span><br><span class="line">1992</span><br><span class="line">1993</span><br><span class="line">1994</span><br><span class="line">1995</span><br><span class="line">1996</span><br><span class="line">1997</span><br><span class="line">1998</span><br><span class="line">1999</span><br><span class="line">2000</span><br><span class="line">2001</span><br><span class="line">2002</span><br><span class="line">2003</span><br><span class="line">2004</span><br><span class="line">2005</span><br><span class="line">2006</span><br><span class="line">2007</span><br><span class="line">2008</span><br><span class="line">2009</span><br><span class="line">2010</span><br><span class="line">2011</span><br><span class="line">2012</span><br><span class="line">2013</span><br><span class="line">2014</span><br><span class="line">2015</span><br><span class="line">2016</span><br><span class="line">2017</span><br><span class="line">2018</span><br><span class="line">2019</span><br><span class="line">2020</span><br><span class="line">2021</span><br><span class="line">2022</span><br><span class="line">2023</span><br><span class="line">2024</span><br><span class="line">2025</span><br><span class="line">2026</span><br><span class="line">2027</span><br><span class="line">2028</span><br><span class="line">2029</span><br><span class="line">2030</span><br><span class="line">2031</span><br><span class="line">2032</span><br><span class="line">2033</span><br><span class="line">2034</span><br><span class="line">2035</span><br><span class="line">2036</span><br><span class="line">2037</span><br><span class="line">2038</span><br><span class="line">2039</span><br><span class="line">2040</span><br><span class="line">2041</span><br><span class="line">2042</span><br><span class="line">2043</span><br><span class="line">2044</span><br><span class="line">2045</span><br><span class="line">2046</span><br><span class="line">2047</span><br><span class="line">2048</span><br><span class="line">2049</span><br><span class="line">2050</span><br><span class="line">2051</span><br><span class="line">2052</span><br><span class="line">2053</span><br><span class="line">2054</span><br><span class="line">2055</span><br><span class="line">2056</span><br><span class="line">2057</span><br><span class="line">2058</span><br><span class="line">2059</span><br><span class="line">2060</span><br><span class="line">2061</span><br><span class="line">2062</span><br><span class="line">2063</span><br><span class="line">2064</span><br><span class="line">2065</span><br><span class="line">2066</span><br><span class="line">2067</span><br><span class="line">2068</span><br><span class="line">2069</span><br><span class="line">2070</span><br><span class="line">2071</span><br><span class="line">2072</span><br><span class="line">2073</span><br><span class="line">2074</span><br><span class="line">2075</span><br><span class="line">2076</span><br><span class="line">2077</span><br><span class="line">2078</span><br><span class="line">2079</span><br><span class="line">2080</span><br><span class="line">2081</span><br><span class="line">2082</span><br><span class="line">2083</span><br><span class="line">2084</span><br><span class="line">2085</span><br><span class="line">2086</span><br><span class="line">2087</span><br><span class="line">2088</span><br><span class="line">2089</span><br><span class="line">2090</span><br><span class="line">2091</span><br><span class="line">2092</span><br><span class="line">2093</span><br><span class="line">2094</span><br><span class="line">2095</span><br><span class="line">2096</span><br><span class="line">2097</span><br><span class="line">2098</span><br><span class="line">2099</span><br><span class="line">2100</span><br><span class="line">2101</span><br><span class="line">2102</span><br><span class="line">2103</span><br><span class="line">2104</span><br><span class="line">2105</span><br><span class="line">2106</span><br><span class="line">2107</span><br><span class="line">2108</span><br><span class="line">2109</span><br><span class="line">2110</span><br><span class="line">2111</span><br><span class="line">2112</span><br><span class="line">2113</span><br><span class="line">2114</span><br><span class="line">2115</span><br><span class="line">2116</span><br><span class="line">2117</span><br><span class="line">2118</span><br><span class="line">2119</span><br><span class="line">2120</span><br><span class="line">2121</span><br><span class="line">2122</span><br><span class="line">2123</span><br><span class="line">2124</span><br><span class="line">2125</span><br><span class="line">2126</span><br><span class="line">2127</span><br><span class="line">2128</span><br><span class="line">2129</span><br><span class="line">2130</span><br><span class="line">2131</span><br><span class="line">2132</span><br><span class="line">2133</span><br><span class="line">2134</span><br><span class="line">2135</span><br><span class="line">2136</span><br><span class="line">2137</span><br><span class="line">2138</span><br><span class="line">2139</span><br><span class="line">2140</span><br><span class="line">2141</span><br><span class="line">2142</span><br><span class="line">2143</span><br><span class="line">2144</span><br><span class="line">2145</span><br><span class="line">2146</span><br><span class="line">2147</span><br><span class="line">2148</span><br><span class="line">2149</span><br><span class="line">2150</span><br><span class="line">2151</span><br><span class="line">2152</span><br><span class="line">2153</span><br><span class="line">2154</span><br><span class="line">2155</span><br><span class="line">2156</span><br><span class="line">2157</span><br><span class="line">2158</span><br><span class="line">2159</span><br><span class="line">2160</span><br><span class="line">2161</span><br><span class="line">2162</span><br><span class="line">2163</span><br><span class="line">2164</span><br><span class="line">2165</span><br><span class="line">2166</span><br><span class="line">2167</span><br><span class="line">2168</span><br><span class="line">2169</span><br><span class="line">2170</span><br><span class="line">2171</span><br><span class="line">2172</span><br><span class="line">2173</span><br><span class="line">2174</span><br><span class="line">2175</span><br><span class="line">2176</span><br><span class="line">2177</span><br><span class="line">2178</span><br><span class="line">2179</span><br><span class="line">2180</span><br><span class="line">2181</span><br><span class="line">2182</span><br><span class="line">2183</span><br><span class="line">2184</span><br><span class="line">2185</span><br><span class="line">2186</span><br><span class="line">2187</span><br><span class="line">2188</span><br><span class="line">2189</span><br><span class="line">2190</span><br><span class="line">2191</span><br><span class="line">2192</span><br><span class="line">2193</span><br><span class="line">2194</span><br><span class="line">2195</span><br><span class="line">2196</span><br><span class="line">2197</span><br><span class="line">2198</span><br><span class="line">2199</span><br><span class="line">2200</span><br><span class="line">2201</span><br><span class="line">2202</span><br><span class="line">2203</span><br><span class="line">2204</span><br><span class="line">2205</span><br><span class="line">2206</span><br><span class="line">2207</span><br><span class="line">2208</span><br><span class="line">2209</span><br><span class="line">2210</span><br><span class="line">2211</span><br><span class="line">2212</span><br><span class="line">2213</span><br><span class="line">2214</span><br><span class="line">2215</span><br><span class="line">2216</span><br><span class="line">2217</span><br><span class="line">2218</span><br><span class="line">2219</span><br><span class="line">2220</span><br><span class="line">2221</span><br><span class="line">2222</span><br><span class="line">2223</span><br><span class="line">2224</span><br><span class="line">2225</span><br><span class="line">2226</span><br><span class="line">2227</span><br><span class="line">2228</span><br><span class="line">2229</span><br><span class="line">2230</span><br><span class="line">2231</span><br><span class="line">2232</span><br><span class="line">2233</span><br><span class="line">2234</span><br><span class="line">2235</span><br><span class="line">2236</span><br><span class="line">2237</span><br><span class="line">2238</span><br><span class="line">2239</span><br><span class="line">2240</span><br><span class="line">2241</span><br><span class="line">2242</span><br><span class="line">2243</span><br><span class="line">2244</span><br><span class="line">2245</span><br><span class="line">2246</span><br><span class="line">2247</span><br><span class="line">2248</span><br><span class="line">2249</span><br><span class="line">2250</span><br><span class="line">2251</span><br><span class="line">2252</span><br><span class="line">2253</span><br><span class="line">2254</span><br><span class="line">2255</span><br><span class="line">2256</span><br><span class="line">2257</span><br><span class="line">2258</span><br><span class="line">2259</span><br><span class="line">2260</span><br><span class="line">2261</span><br><span class="line">2262</span><br><span class="line">2263</span><br><span class="line">2264</span><br><span class="line">2265</span><br><span class="line">2266</span><br><span class="line">2267</span><br><span class="line">2268</span><br><span class="line">2269</span><br><span class="line">2270</span><br><span class="line">2271</span><br><span class="line">2272</span><br><span class="line">2273</span><br><span class="line">2274</span><br><span class="line">2275</span><br><span class="line">2276</span><br><span class="line">2277</span><br><span class="line">2278</span><br><span class="line">2279</span><br><span class="line">2280</span><br><span class="line">2281</span><br><span class="line">2282</span><br><span class="line">2283</span><br><span class="line">2284</span><br><span class="line">2285</span><br><span class="line">2286</span><br><span class="line">2287</span><br><span class="line">2288</span><br><span class="line">2289</span><br><span class="line">2290</span><br><span class="line">2291</span><br><span class="line">2292</span><br><span class="line">2293</span><br><span class="line">2294</span><br><span class="line">2295</span><br><span class="line">2296</span><br><span class="line">2297</span><br><span class="line">2298</span><br><span class="line">2299</span><br><span class="line">2300</span><br><span class="line">2301</span><br><span class="line">2302</span><br><span class="line">2303</span><br><span class="line">2304</span><br><span class="line">2305</span><br><span class="line">2306</span><br><span class="line">2307</span><br><span class="line">2308</span><br><span class="line">2309</span><br><span class="line">2310</span><br><span class="line">2311</span><br><span class="line">2312</span><br><span class="line">2313</span><br><span class="line">2314</span><br><span class="line">2315</span><br><span class="line">2316</span><br><span class="line">2317</span><br><span class="line">2318</span><br><span class="line">2319</span><br><span class="line">2320</span><br><span class="line">2321</span><br><span class="line">2322</span><br><span class="line">2323</span><br><span class="line">2324</span><br><span class="line">2325</span><br><span class="line">2326</span><br><span class="line">2327</span><br><span class="line">2328</span><br><span class="line">2329</span><br><span class="line">2330</span><br><span class="line">2331</span><br><span class="line">2332</span><br><span class="line">2333</span><br><span class="line">2334</span><br><span class="line">2335</span><br><span class="line">2336</span><br><span class="line">2337</span><br><span class="line">2338</span><br><span class="line">2339</span><br><span class="line">2340</span><br><span class="line">2341</span><br><span class="line">2342</span><br><span class="line">2343</span><br><span class="line">2344</span><br><span class="line">2345</span><br><span class="line">2346</span><br><span class="line">2347</span><br><span class="line">2348</span><br><span class="line">2349</span><br><span class="line">2350</span><br><span class="line">2351</span><br><span class="line">2352</span><br><span class="line">2353</span><br><span class="line">2354</span><br><span class="line">2355</span><br><span class="line">2356</span><br><span class="line">2357</span><br><span class="line">2358</span><br><span class="line">2359</span><br><span class="line">2360</span><br><span class="line">2361</span><br><span class="line">2362</span><br><span class="line">2363</span><br><span class="line">2364</span><br><span class="line">2365</span><br><span class="line">2366</span><br><span class="line">2367</span><br><span class="line">2368</span><br><span class="line">2369</span><br><span class="line">2370</span><br><span class="line">2371</span><br><span class="line">2372</span><br><span class="line">2373</span><br><span class="line">2374</span><br><span class="line">2375</span><br><span class="line">2376</span><br><span class="line">2377</span><br><span class="line">2378</span><br><span class="line">2379</span><br><span class="line">2380</span><br><span class="line">2381</span><br><span class="line">2382</span><br><span class="line">2383</span><br><span class="line">2384</span><br><span class="line">2385</span><br><span class="line">2386</span><br><span class="line">2387</span><br><span class="line">2388</span><br><span class="line">2389</span><br><span class="line">2390</span><br><span class="line">2391</span><br><span class="line">2392</span><br><span class="line">2393</span><br><span class="line">2394</span><br><span class="line">2395</span><br><span class="line">2396</span><br><span class="line">2397</span><br><span class="line">2398</span><br><span class="line">2399</span><br><span class="line">2400</span><br><span class="line">2401</span><br><span class="line">2402</span><br><span class="line">2403</span><br><span class="line">2404</span><br><span class="line">2405</span><br><span class="line">2406</span><br><span class="line">2407</span><br><span class="line">2408</span><br><span class="line">2409</span><br><span class="line">2410</span><br><span class="line">2411</span><br><span class="line">2412</span><br><span class="line">2413</span><br><span class="line">2414</span><br><span class="line">2415</span><br><span class="line">2416</span><br><span class="line">2417</span><br><span class="line">2418</span><br><span class="line">2419</span><br><span class="line">2420</span><br><span class="line">2421</span><br><span class="line">2422</span><br><span class="line">2423</span><br><span class="line">2424</span><br><span class="line">2425</span><br><span class="line">2426</span><br><span class="line">2427</span><br><span class="line">2428</span><br><span class="line">2429</span><br><span class="line">2430</span><br><span class="line">2431</span><br><span class="line">2432</span><br><span class="line">2433</span><br><span class="line">2434</span><br><span class="line">2435</span><br><span class="line">2436</span><br><span class="line">2437</span><br><span class="line">2438</span><br><span class="line">2439</span><br><span class="line">2440</span><br><span class="line">2441</span><br><span class="line">2442</span><br><span class="line">2443</span><br><span class="line">2444</span><br><span class="line">2445</span><br><span class="line">2446</span><br><span class="line">2447</span><br><span class="line">2448</span><br><span class="line">2449</span><br><span class="line">2450</span><br><span class="line">2451</span><br><span class="line">2452</span><br><span class="line">2453</span><br><span class="line">2454</span><br><span class="line">2455</span><br><span class="line">2456</span><br><span class="line">2457</span><br><span class="line">2458</span><br><span class="line">2459</span><br><span class="line">2460</span><br><span class="line">2461</span><br><span class="line">2462</span><br><span class="line">2463</span><br><span class="line">2464</span><br><span class="line">2465</span><br><span class="line">2466</span><br><span class="line">2467</span><br><span class="line">2468</span><br><span class="line">2469</span><br><span class="line">2470</span><br><span class="line">2471</span><br><span class="line">2472</span><br><span class="line">2473</span><br><span class="line">2474</span><br><span class="line">2475</span><br><span class="line">2476</span><br><span class="line">2477</span><br><span class="line">2478</span><br><span class="line">2479</span><br><span class="line">2480</span><br><span class="line">2481</span><br><span class="line">2482</span><br><span class="line">2483</span><br><span class="line">2484</span><br><span class="line">2485</span><br><span class="line">2486</span><br><span class="line">2487</span><br><span class="line">2488</span><br><span class="line">2489</span><br><span class="line">2490</span><br><span class="line">2491</span><br><span class="line">2492</span><br><span class="line">2493</span><br><span class="line">2494</span><br><span class="line">2495</span><br><span class="line">2496</span><br><span class="line">2497</span><br><span class="line">2498</span><br><span class="line">2499</span><br><span class="line">2500</span><br><span class="line">2501</span><br><span class="line">2502</span><br><span class="line">2503</span><br><span class="line">2504</span><br><span class="line">2505</span><br><span class="line">2506</span><br><span class="line">2507</span><br><span class="line">2508</span><br><span class="line">2509</span><br><span class="line">2510</span><br><span class="line">2511</span><br><span class="line">2512</span><br><span class="line">2513</span><br><span class="line">2514</span><br><span class="line">2515</span><br><span class="line">2516</span><br><span class="line">2517</span><br><span class="line">2518</span><br><span class="line">2519</span><br><span class="line">2520</span><br><span class="line">2521</span><br><span class="line">2522</span><br><span class="line">2523</span><br><span class="line">2524</span><br><span class="line">2525</span><br><span class="line">2526</span><br><span class="line">2527</span><br><span class="line">2528</span><br><span class="line">2529</span><br><span class="line">2530</span><br><span class="line">2531</span><br><span class="line">2532</span><br><span class="line">2533</span><br><span class="line">2534</span><br><span class="line">2535</span><br><span class="line">2536</span><br><span class="line">2537</span><br><span class="line">2538</span><br><span class="line">2539</span><br><span class="line">2540</span><br><span class="line">2541</span><br><span class="line">2542</span><br><span class="line">2543</span><br><span class="line">2544</span><br><span class="line">2545</span><br><span class="line">2546</span><br><span class="line">2547</span><br><span class="line">2548</span><br><span class="line">2549</span><br><span class="line">2550</span><br><span class="line">2551</span><br><span class="line">2552</span><br><span class="line">2553</span><br><span class="line">2554</span><br><span class="line">2555</span><br><span class="line">2556</span><br><span class="line">2557</span><br><span class="line">2558</span><br><span class="line">2559</span><br><span class="line">2560</span><br><span class="line">2561</span><br><span class="line">2562</span><br><span class="line">2563</span><br><span class="line">2564</span><br><span class="line">2565</span><br><span class="line">2566</span><br><span class="line">2567</span><br><span class="line">2568</span><br><span class="line">2569</span><br><span class="line">2570</span><br><span class="line">2571</span><br><span class="line">2572</span><br><span class="line">2573</span><br><span class="line">2574</span><br><span class="line">2575</span><br><span class="line">2576</span><br><span class="line">2577</span><br><span class="line">2578</span><br><span class="line">2579</span><br><span class="line">2580</span><br><span class="line">2581</span><br><span class="line">2582</span><br><span class="line">2583</span><br><span class="line">2584</span><br><span class="line">2585</span><br><span class="line">2586</span><br><span class="line">2587</span><br><span class="line">2588</span><br><span class="line">2589</span><br><span class="line">2590</span><br><span class="line">2591</span><br><span class="line">2592</span><br><span class="line">2593</span><br><span class="line">2594</span><br><span class="line">2595</span><br><span class="line">2596</span><br><span class="line">2597</span><br><span class="line">2598</span><br><span class="line">2599</span><br><span class="line">2600</span><br><span class="line">2601</span><br><span class="line">2602</span><br><span class="line">2603</span><br><span class="line">2604</span><br><span class="line">2605</span><br><span class="line">2606</span><br><span class="line">2607</span><br><span class="line">2608</span><br><span class="line">2609</span><br><span class="line">2610</span><br><span class="line">2611</span><br><span class="line">2612</span><br><span class="line">2613</span><br><span class="line">2614</span><br><span class="line">2615</span><br><span class="line">2616</span><br><span class="line">2617</span><br><span class="line">2618</span><br><span class="line">2619</span><br><span class="line">2620</span><br><span class="line">2621</span><br><span class="line">2622</span><br><span class="line">2623</span><br><span class="line">2624</span><br><span class="line">2625</span><br><span class="line">2626</span><br><span class="line">2627</span><br><span class="line">2628</span><br><span class="line">2629</span><br><span class="line">2630</span><br><span class="line">2631</span><br><span class="line">2632</span><br><span class="line">2633</span><br><span class="line">2634</span><br><span class="line">2635</span><br><span class="line">2636</span><br><span class="line">2637</span><br><span class="line">2638</span><br><span class="line">2639</span><br><span class="line">2640</span><br><span class="line">2641</span><br><span class="line">2642</span><br><span class="line">2643</span><br><span class="line">2644</span><br><span class="line">2645</span><br><span class="line">2646</span><br><span class="line">2647</span><br><span class="line">2648</span><br><span class="line">2649</span><br><span class="line">2650</span><br><span class="line">2651</span><br><span class="line">2652</span><br><span class="line">2653</span><br><span class="line">2654</span><br><span class="line">2655</span><br><span class="line">2656</span><br><span class="line">2657</span><br><span class="line">2658</span><br><span class="line">2659</span><br><span class="line">2660</span><br><span class="line">2661</span><br><span class="line">2662</span><br><span class="line">2663</span><br><span class="line">2664</span><br><span class="line">2665</span><br><span class="line">2666</span><br><span class="line">2667</span><br><span class="line">2668</span><br><span class="line">2669</span><br><span class="line">2670</span><br><span class="line">2671</span><br><span class="line">2672</span><br><span class="line">2673</span><br><span class="line">2674</span><br><span class="line">2675</span><br><span class="line">2676</span><br><span class="line">2677</span><br><span class="line">2678</span><br><span class="line">2679</span><br><span class="line">2680</span><br><span class="line">2681</span><br><span class="line">2682</span><br><span class="line">2683</span><br><span class="line">2684</span><br><span class="line">2685</span><br><span class="line">2686</span><br><span class="line">2687</span><br><span class="line">2688</span><br><span class="line">2689</span><br><span class="line">2690</span><br><span class="line">2691</span><br><span class="line">2692</span><br><span class="line">2693</span><br><span class="line">2694</span><br><span class="line">2695</span><br><span class="line">2696</span><br><span class="line">2697</span><br><span class="line">2698</span><br><span class="line">2699</span><br><span class="line">2700</span><br><span class="line">2701</span><br><span class="line">2702</span><br><span class="line">2703</span><br><span class="line">2704</span><br><span class="line">2705</span><br><span class="line">2706</span><br><span class="line">2707</span><br><span class="line">2708</span><br><span class="line">2709</span><br><span class="line">2710</span><br><span class="line">2711</span><br><span class="line">2712</span><br><span class="line">2713</span><br><span class="line">2714</span><br><span class="line">2715</span><br><span class="line">2716</span><br><span class="line">2717</span><br><span class="line">2718</span><br><span class="line">2719</span><br><span class="line">2720</span><br><span class="line">2721</span><br><span class="line">2722</span><br><span class="line">2723</span><br><span class="line">2724</span><br><span class="line">2725</span><br><span class="line">2726</span><br><span class="line">2727</span><br><span class="line">2728</span><br><span class="line">2729</span><br><span class="line">2730</span><br><span class="line">2731</span><br><span class="line">2732</span><br><span class="line">2733</span><br><span class="line">2734</span><br><span class="line">2735</span><br><span class="line">2736</span><br><span class="line">2737</span><br><span class="line">2738</span><br><span class="line">2739</span><br><span class="line">2740</span><br><span class="line">2741</span><br><span class="line">2742</span><br><span class="line">2743</span><br><span class="line">2744</span><br><span class="line">2745</span><br><span class="line">2746</span><br><span class="line">2747</span><br><span class="line">2748</span><br><span class="line">2749</span><br><span class="line">2750</span><br><span class="line">2751</span><br><span class="line">2752</span><br><span class="line">2753</span><br><span class="line">2754</span><br><span class="line">2755</span><br><span class="line">2756</span><br><span class="line">2757</span><br><span class="line">2758</span><br><span class="line">2759</span><br><span class="line">2760</span><br><span class="line">2761</span><br><span class="line">2762</span><br><span class="line">2763</span><br><span class="line">2764</span><br><span class="line">2765</span><br><span class="line">2766</span><br><span class="line">2767</span><br><span class="line">2768</span><br><span class="line">2769</span><br><span class="line">2770</span><br><span class="line">2771</span><br><span class="line">2772</span><br><span class="line">2773</span><br><span class="line">2774</span><br><span class="line">2775</span><br><span class="line">2776</span><br><span class="line">2777</span><br><span class="line">2778</span><br><span class="line">2779</span><br><span class="line">2780</span><br><span class="line">2781</span><br><span class="line">2782</span><br><span class="line">2783</span><br><span class="line">2784</span><br><span class="line">2785</span><br><span class="line">2786</span><br><span class="line">2787</span><br><span class="line">2788</span><br><span class="line">2789</span><br><span class="line">2790</span><br><span class="line">2791</span><br><span class="line">2792</span><br><span class="line">2793</span><br><span class="line">2794</span><br><span class="line">2795</span><br><span class="line">2796</span><br><span class="line">2797</span><br><span class="line">2798</span><br><span class="line">2799</span><br><span class="line">2800</span><br><span class="line">2801</span><br><span class="line">2802</span><br><span class="line">2803</span><br><span class="line">2804</span><br><span class="line">2805</span><br><span class="line">2806</span><br><span class="line">2807</span><br><span class="line">2808</span><br><span class="line">2809</span><br><span class="line">2810</span><br><span class="line">2811</span><br><span class="line">2812</span><br><span class="line">2813</span><br><span class="line">2814</span><br><span class="line">2815</span><br><span class="line">2816</span><br><span class="line">2817</span><br><span class="line">2818</span><br><span class="line">2819</span><br><span class="line">2820</span><br><span class="line">2821</span><br><span class="line">2822</span><br><span class="line">2823</span><br><span class="line">2824</span><br><span class="line">2825</span><br><span class="line">2826</span><br><span class="line">2827</span><br><span class="line">2828</span><br><span class="line">2829</span><br><span class="line">2830</span><br><span class="line">2831</span><br><span class="line">2832</span><br><span class="line">2833</span><br><span class="line">2834</span><br><span class="line">2835</span><br><span class="line">2836</span><br><span class="line">2837</span><br><span class="line">2838</span><br><span class="line">2839</span><br><span class="line">2840</span><br><span class="line">2841</span><br><span class="line">2842</span><br><span class="line">2843</span><br><span class="line">2844</span><br><span class="line">2845</span><br><span class="line">2846</span><br><span class="line">2847</span><br><span class="line">2848</span><br><span class="line">2849</span><br><span class="line">2850</span><br><span class="line">2851</span><br><span class="line">2852</span><br><span class="line">2853</span><br><span class="line">2854</span><br><span class="line">2855</span><br><span class="line">2856</span><br><span class="line">2857</span><br><span class="line">2858</span><br><span class="line">2859</span><br><span class="line">2860</span><br><span class="line">2861</span><br><span class="line">2862</span><br><span class="line">2863</span><br><span class="line">2864</span><br><span class="line">2865</span><br><span class="line">2866</span><br><span class="line">2867</span><br><span class="line">2868</span><br><span class="line">2869</span><br><span class="line">2870</span><br><span class="line">2871</span><br><span class="line">2872</span><br><span class="line">2873</span><br><span class="line">2874</span><br><span class="line">2875</span><br><span class="line">2876</span><br><span class="line">2877</span><br><span class="line">2878</span><br><span class="line">2879</span><br><span class="line">2880</span><br><span class="line">2881</span><br><span class="line">2882</span><br><span class="line">2883</span><br><span class="line">2884</span><br><span class="line">2885</span><br><span class="line">2886</span><br><span class="line">2887</span><br><span class="line">2888</span><br><span class="line">2889</span><br><span class="line">2890</span><br><span class="line">2891</span><br><span class="line">2892</span><br><span class="line">2893</span><br><span class="line">2894</span><br><span class="line">2895</span><br><span class="line">2896</span><br><span class="line">2897</span><br><span class="line">2898</span><br><span class="line">2899</span><br><span class="line">2900</span><br><span class="line">2901</span><br><span class="line">2902</span><br><span class="line">2903</span><br><span class="line">2904</span><br><span class="line">2905</span><br><span class="line">2906</span><br><span class="line">2907</span><br><span class="line">2908</span><br><span class="line">2909</span><br><span class="line">2910</span><br><span class="line">2911</span><br><span class="line">2912</span><br><span class="line">2913</span><br><span class="line">2914</span><br><span class="line">2915</span><br><span class="line">2916</span><br><span class="line">2917</span><br><span class="line">2918</span><br><span class="line">2919</span><br><span class="line">2920</span><br><span class="line">2921</span><br><span class="line">2922</span><br><span class="line">2923</span><br><span class="line">2924</span><br><span class="line">2925</span><br><span class="line">2926</span><br><span class="line">2927</span><br><span class="line">2928</span><br><span class="line">2929</span><br><span class="line">2930</span><br><span class="line">2931</span><br><span class="line">2932</span><br><span class="line">2933</span><br><span class="line">2934</span><br><span class="line">2935</span><br><span class="line">2936</span><br><span class="line">2937</span><br><span class="line">2938</span><br><span class="line">2939</span><br><span class="line">2940</span><br><span class="line">2941</span><br><span class="line">2942</span><br><span class="line">2943</span><br><span class="line">2944</span><br><span class="line">2945</span><br><span class="line">2946</span><br><span class="line">2947</span><br><span class="line">2948</span><br><span class="line">2949</span><br><span class="line">2950</span><br><span class="line">2951</span><br><span class="line">2952</span><br><span class="line">2953</span><br><span class="line">2954</span><br><span class="line">2955</span><br><span class="line">2956</span><br><span class="line">2957</span><br><span class="line">2958</span><br><span class="line">2959</span><br><span class="line">2960</span><br><span class="line">2961</span><br><span class="line">2962</span><br><span class="line">2963</span><br><span class="line">2964</span><br><span class="line">2965</span><br><span class="line">2966</span><br><span class="line">2967</span><br><span class="line">2968</span><br><span class="line">2969</span><br><span class="line">2970</span><br><span class="line">2971</span><br><span class="line">2972</span><br><span class="line">2973</span><br><span class="line">2974</span><br><span class="line">2975</span><br><span class="line">2976</span><br><span class="line">2977</span><br><span class="line">2978</span><br><span class="line">2979</span><br><span class="line">2980</span><br><span class="line">2981</span><br><span class="line">2982</span><br><span class="line">2983</span><br><span class="line">2984</span><br><span class="line">2985</span><br><span class="line">2986</span><br><span class="line">2987</span><br><span class="line">2988</span><br><span class="line">2989</span><br><span class="line">2990</span><br><span class="line">2991</span><br><span class="line">2992</span><br><span class="line">2993</span><br><span class="line">2994</span><br><span class="line">2995</span><br><span class="line">2996</span><br><span class="line">2997</span><br><span class="line">2998</span><br><span class="line">2999</span><br><span class="line">3000</span><br><span class="line">3001</span><br><span class="line">3002</span><br><span class="line">3003</span><br><span class="line">3004</span><br><span class="line">3005</span><br><span class="line">3006</span><br><span class="line">3007</span><br><span class="line">3008</span><br><span class="line">3009</span><br><span class="line">3010</span><br><span class="line">3011</span><br><span class="line">3012</span><br><span class="line">3013</span><br><span class="line">3014</span><br><span class="line">3015</span><br><span class="line">3016</span><br><span class="line">3017</span><br><span class="line">3018</span><br><span class="line">3019</span><br><span class="line">3020</span><br><span class="line">3021</span><br><span class="line">3022</span><br><span class="line">3023</span><br><span class="line">3024</span><br><span class="line">3025</span><br><span class="line">3026</span><br><span class="line">3027</span><br><span class="line">3028</span><br><span class="line">3029</span><br><span class="line">3030</span><br><span class="line">3031</span><br><span class="line">3032</span><br><span class="line">3033</span><br><span class="line">3034</span><br><span class="line">3035</span><br><span class="line">3036</span><br><span class="line">3037</span><br><span class="line">3038</span><br><span class="line">3039</span><br><span class="line">3040</span><br><span class="line">3041</span><br><span class="line">3042</span><br><span class="line">3043</span><br><span class="line">3044</span><br><span class="line">3045</span><br><span class="line">3046</span><br><span class="line">3047</span><br><span class="line">3048</span><br><span class="line">3049</span><br><span class="line">3050</span><br><span class="line">3051</span><br><span class="line">3052</span><br><span class="line">3053</span><br><span class="line">3054</span><br><span class="line">3055</span><br><span class="line">3056</span><br><span class="line">3057</span><br><span class="line">3058</span><br><span class="line">3059</span><br><span class="line">3060</span><br><span class="line">3061</span><br><span class="line">3062</span><br><span class="line">3063</span><br><span class="line">3064</span><br><span class="line">3065</span><br><span class="line">3066</span><br><span class="line">3067</span><br><span class="line">3068</span><br><span class="line">3069</span><br><span class="line">3070</span><br><span class="line">3071</span><br><span class="line">3072</span><br><span class="line">3073</span><br><span class="line">3074</span><br><span class="line">3075</span><br><span class="line">3076</span><br><span class="line">3077</span><br><span class="line">3078</span><br><span class="line">3079</span><br><span class="line">3080</span><br><span class="line">3081</span><br><span class="line">3082</span><br><span class="line">3083</span><br><span class="line">3084</span><br><span class="line">3085</span><br><span class="line">3086</span><br><span class="line">3087</span><br><span class="line">3088</span><br><span class="line">3089</span><br><span class="line">3090</span><br><span class="line">3091</span><br><span class="line">3092</span><br><span class="line">3093</span><br><span class="line">3094</span><br><span class="line">3095</span><br><span class="line">3096</span><br><span class="line">3097</span><br><span class="line">3098</span><br><span class="line">3099</span><br><span class="line">3100</span><br><span class="line">3101</span><br><span class="line">3102</span><br><span class="line">3103</span><br><span class="line">3104</span><br><span class="line">3105</span><br><span class="line">3106</span><br><span class="line">3107</span><br><span class="line">3108</span><br><span class="line">3109</span><br><span class="line">3110</span><br><span class="line">3111</span><br><span class="line">3112</span><br><span class="line">3113</span><br><span class="line">3114</span><br><span class="line">3115</span><br><span class="line">3116</span><br><span class="line">3117</span><br><span class="line">3118</span><br><span class="line">3119</span><br><span class="line">3120</span><br><span class="line">3121</span><br><span class="line">3122</span><br><span class="line">3123</span><br><span class="line">3124</span><br><span class="line">3125</span><br><span class="line">3126</span><br><span class="line">3127</span><br><span class="line">3128</span><br><span class="line">3129</span><br><span class="line">3130</span><br><span class="line">3131</span><br><span class="line">3132</span><br><span class="line">3133</span><br><span class="line">3134</span><br><span class="line">3135</span><br><span class="line">3136</span><br><span class="line">3137</span><br><span class="line">3138</span><br><span class="line">3139</span><br><span class="line">3140</span><br><span class="line">3141</span><br><span class="line">3142</span><br><span class="line">3143</span><br><span class="line">3144</span><br><span class="line">3145</span><br><span class="line">3146</span><br><span class="line">3147</span><br><span class="line">3148</span><br><span class="line">3149</span><br><span class="line">3150</span><br><span class="line">3151</span><br><span class="line">3152</span><br><span class="line">3153</span><br><span class="line">3154</span><br><span class="line">3155</span><br><span class="line">3156</span><br><span class="line">3157</span><br><span class="line">3158</span><br><span class="line">3159</span><br><span class="line">3160</span><br><span class="line">3161</span><br><span class="line">3162</span><br><span class="line">3163</span><br><span class="line">3164</span><br><span class="line">3165</span><br><span class="line">3166</span><br><span class="line">3167</span><br><span class="line">3168</span><br><span class="line">3169</span><br><span class="line">3170</span><br><span class="line">3171</span><br><span class="line">3172</span><br><span class="line">3173</span><br><span class="line">3174</span><br><span class="line">3175</span><br><span class="line">3176</span><br><span class="line">3177</span><br><span class="line">3178</span><br><span class="line">3179</span><br><span class="line">3180</span><br><span class="line">3181</span><br><span class="line">3182</span><br><span class="line">3183</span><br><span class="line">3184</span><br><span class="line">3185</span><br><span class="line">3186</span><br><span class="line">3187</span><br><span class="line">3188</span><br><span class="line">3189</span><br><span class="line">3190</span><br><span class="line">3191</span><br><span class="line">3192</span><br><span class="line">3193</span><br><span class="line">3194</span><br><span class="line">3195</span><br><span class="line">3196</span><br><span class="line">3197</span><br><span class="line">3198</span><br><span class="line">3199</span><br><span class="line">3200</span><br><span class="line">3201</span><br><span class="line">3202</span><br><span class="line">3203</span><br><span class="line">3204</span><br><span class="line">3205</span><br><span class="line">3206</span><br><span class="line">3207</span><br><span class="line">3208</span><br><span class="line">3209</span><br><span class="line">3210</span><br><span class="line">3211</span><br><span class="line">3212</span><br><span class="line">3213</span><br><span class="line">3214</span><br><span class="line">3215</span><br><span class="line">3216</span><br><span class="line">3217</span><br><span class="line">3218</span><br><span class="line">3219</span><br><span class="line">3220</span><br><span class="line">3221</span><br><span class="line">3222</span><br><span class="line">3223</span><br><span class="line">3224</span><br><span class="line">3225</span><br><span class="line">3226</span><br><span class="line">3227</span><br><span class="line">3228</span><br><span class="line">3229</span><br><span class="line">3230</span><br><span class="line">3231</span><br><span class="line">3232</span><br><span class="line">3233</span><br><span class="line">3234</span><br><span class="line">3235</span><br><span class="line">3236</span><br><span class="line">3237</span><br><span class="line">3238</span><br><span class="line">3239</span><br><span class="line">3240</span><br><span class="line">3241</span><br><span class="line">3242</span><br><span class="line">3243</span><br><span class="line">3244</span><br><span class="line">3245</span><br><span class="line">3246</span><br><span class="line">3247</span><br><span class="line">3248</span><br><span class="line">3249</span><br><span class="line">3250</span><br><span class="line">3251</span><br><span class="line">3252</span><br><span class="line">3253</span><br><span class="line">3254</span><br><span class="line">3255</span><br><span class="line">3256</span><br><span class="line">3257</span><br><span class="line">3258</span><br><span class="line">3259</span><br><span class="line">3260</span><br><span class="line">3261</span><br><span class="line">3262</span><br><span class="line">3263</span><br><span class="line">3264</span><br><span class="line">3265</span><br><span class="line">3266</span><br><span class="line">3267</span><br><span class="line">3268</span><br><span class="line">3269</span><br><span class="line">3270</span><br><span class="line">3271</span><br><span class="line">3272</span><br><span class="line">3273</span><br><span class="line">3274</span><br><span class="line">3275</span><br><span class="line">3276</span><br><span class="line">3277</span><br><span class="line">3278</span><br><span class="line">3279</span><br><span class="line">3280</span><br><span class="line">3281</span><br><span class="line">3282</span><br><span class="line">3283</span><br><span class="line">3284</span><br><span class="line">3285</span><br><span class="line">3286</span><br><span class="line">3287</span><br><span class="line">3288</span><br><span class="line">3289</span><br><span class="line">3290</span><br><span class="line">3291</span><br><span class="line">3292</span><br><span class="line">3293</span><br><span class="line">3294</span><br><span class="line">3295</span><br><span class="line">3296</span><br><span class="line">3297</span><br><span class="line">3298</span><br><span class="line">3299</span><br><span class="line">3300</span><br><span class="line">3301</span><br><span class="line">3302</span><br><span class="line">3303</span><br><span class="line">3304</span><br><span class="line">3305</span><br><span class="line">3306</span><br><span class="line">3307</span><br><span class="line">3308</span><br><span class="line">3309</span><br><span class="line">3310</span><br><span class="line">3311</span><br><span class="line">3312</span><br><span class="line">3313</span><br><span class="line">3314</span><br><span class="line">3315</span><br><span class="line">3316</span><br><span class="line">3317</span><br><span class="line">3318</span><br><span class="line">3319</span><br><span class="line">3320</span><br><span class="line">3321</span><br><span class="line">3322</span><br><span class="line">3323</span><br><span class="line">3324</span><br><span class="line">3325</span><br><span class="line">3326</span><br><span class="line">3327</span><br><span class="line">3328</span><br><span class="line">3329</span><br><span class="line">3330</span><br><span class="line">3331</span><br><span class="line">3332</span><br><span class="line">3333</span><br><span class="line">3334</span><br><span class="line">3335</span><br><span class="line">3336</span><br><span class="line">3337</span><br><span class="line">3338</span><br><span class="line">3339</span><br><span class="line">3340</span><br><span class="line">3341</span><br><span class="line">3342</span><br><span class="line">3343</span><br><span class="line">3344</span><br><span class="line">3345</span><br><span class="line">3346</span><br><span class="line">3347</span><br><span class="line">3348</span><br><span class="line">3349</span><br><span class="line">3350</span><br><span class="line">3351</span><br><span class="line">3352</span><br><span class="line">3353</span><br><span class="line">3354</span><br><span class="line">3355</span><br><span class="line">3356</span><br><span class="line">3357</span><br><span class="line">3358</span><br><span class="line">3359</span><br><span class="line">3360</span><br><span class="line">3361</span><br><span class="line">3362</span><br><span class="line">3363</span><br><span class="line">3364</span><br><span class="line">3365</span><br><span class="line">3366</span><br><span class="line">3367</span><br><span class="line">3368</span><br><span class="line">3369</span><br><span class="line">3370</span><br><span class="line">3371</span><br><span class="line">3372</span><br><span class="line">3373</span><br><span class="line">3374</span><br><span class="line">3375</span><br><span class="line">3376</span><br><span class="line">3377</span><br><span class="line">3378</span><br><span class="line">3379</span><br><span class="line">3380</span><br><span class="line">3381</span><br><span class="line">3382</span><br><span class="line">3383</span><br><span class="line">3384</span><br><span class="line">3385</span><br><span class="line">3386</span><br><span class="line">3387</span><br><span class="line">3388</span><br><span class="line">3389</span><br><span class="line">3390</span><br><span class="line">3391</span><br><span class="line">3392</span><br><span class="line">3393</span><br><span class="line">3394</span><br><span class="line">3395</span><br><span class="line">3396</span><br><span class="line">3397</span><br><span class="line">3398</span><br><span class="line">3399</span><br><span class="line">3400</span><br><span class="line">3401</span><br><span class="line">3402</span><br><span class="line">3403</span><br><span class="line">3404</span><br><span class="line">3405</span><br><span class="line">3406</span><br><span class="line">3407</span><br><span class="line">3408</span><br><span class="line">3409</span><br><span class="line">3410</span><br><span class="line">3411</span><br><span class="line">3412</span><br><span class="line">3413</span><br><span class="line">3414</span><br><span class="line">3415</span><br><span class="line">3416</span><br><span class="line">3417</span><br><span class="line">3418</span><br><span class="line">3419</span><br><span class="line">3420</span><br><span class="line">3421</span><br><span class="line">3422</span><br><span class="line">3423</span><br><span class="line">3424</span><br><span class="line">3425</span><br><span class="line">3426</span><br><span class="line">3427</span><br><span class="line">3428</span><br><span class="line">3429</span><br><span class="line">3430</span><br><span class="line">3431</span><br><span class="line">3432</span><br><span class="line">3433</span><br><span class="line">3434</span><br><span class="line">3435</span><br><span class="line">3436</span><br><span class="line">3437</span><br><span class="line">3438</span><br><span class="line">3439</span><br><span class="line">3440</span><br><span class="line">3441</span><br><span class="line">3442</span><br><span class="line">3443</span><br><span class="line">3444</span><br><span class="line">3445</span><br><span class="line">3446</span><br><span class="line">3447</span><br><span class="line">3448</span><br><span class="line">3449</span><br><span class="line">3450</span><br><span class="line">3451</span><br><span class="line">3452</span><br><span class="line">3453</span><br><span class="line">3454</span><br><span class="line">3455</span><br><span class="line">3456</span><br><span class="line">3457</span><br><span class="line">3458</span><br><span class="line">3459</span><br><span class="line">3460</span><br><span class="line">3461</span><br><span class="line">3462</span><br><span class="line">3463</span><br><span class="line">3464</span><br><span class="line">3465</span><br><span class="line">3466</span><br><span class="line">3467</span><br><span class="line">3468</span><br><span class="line">3469</span><br><span class="line">3470</span><br><span class="line">3471</span><br><span class="line">3472</span><br><span class="line">3473</span><br><span class="line">3474</span><br><span class="line">3475</span><br><span class="line">3476</span><br><span class="line">3477</span><br><span class="line">3478</span><br><span class="line">3479</span><br><span class="line">3480</span><br><span class="line">3481</span><br><span class="line">3482</span><br><span class="line">3483</span><br><span class="line">3484</span><br><span class="line">3485</span><br><span class="line">3486</span><br><span class="line">3487</span><br><span class="line">3488</span><br><span class="line">3489</span><br><span class="line">3490</span><br><span class="line">3491</span><br><span class="line">3492</span><br><span class="line">3493</span><br><span class="line">3494</span><br><span class="line">3495</span><br><span class="line">3496</span><br><span class="line">3497</span><br><span class="line">3498</span><br><span class="line">3499</span><br><span class="line">3500</span><br><span class="line">3501</span><br><span class="line">3502</span><br><span class="line">3503</span><br><span class="line">3504</span><br><span class="line">3505</span><br><span class="line">3506</span><br><span class="line">3507</span><br><span class="line">3508</span><br><span class="line">3509</span><br><span class="line">3510</span><br><span class="line">3511</span><br><span class="line">3512</span><br><span class="line">3513</span><br><span class="line">3514</span><br><span class="line">3515</span><br><span class="line">3516</span><br><span class="line">3517</span><br><span class="line">3518</span><br><span class="line">3519</span><br><span class="line">3520</span><br><span class="line">3521</span><br><span class="line">3522</span><br><span class="line">3523</span><br><span class="line">3524</span><br><span class="line">3525</span><br><span class="line">3526</span><br><span class="line">3527</span><br><span class="line">3528</span><br><span class="line">3529</span><br><span class="line">3530</span><br><span class="line">3531</span><br><span class="line">3532</span><br><span class="line">3533</span><br><span class="line">3534</span><br><span class="line">3535</span><br><span class="line">3536</span><br><span class="line">3537</span><br><span class="line">3538</span><br><span class="line">3539</span><br><span class="line">3540</span><br><span class="line">3541</span><br><span class="line">3542</span><br><span class="line">3543</span><br><span class="line">3544</span><br><span class="line">3545</span><br><span class="line">3546</span><br><span class="line">3547</span><br><span class="line">3548</span><br><span class="line">3549</span><br><span class="line">3550</span><br><span class="line">3551</span><br><span class="line">3552</span><br><span class="line">3553</span><br><span class="line">3554</span><br><span class="line">3555</span><br><span class="line">3556</span><br><span class="line">3557</span><br><span class="line">3558</span><br><span class="line">3559</span><br><span class="line">3560</span><br><span class="line">3561</span><br><span class="line">3562</span><br><span class="line">3563</span><br><span class="line">3564</span><br><span class="line">3565</span><br><span class="line">3566</span><br><span class="line">3567</span><br><span class="line">3568</span><br><span class="line">3569</span><br><span class="line">3570</span><br><span class="line">3571</span><br><span class="line">3572</span><br><span class="line">3573</span><br><span class="line">3574</span><br><span class="line">3575</span><br><span class="line">3576</span><br><span class="line">3577</span><br><span class="line">3578</span><br><span class="line">3579</span><br><span class="line">3580</span><br><span class="line">3581</span><br><span class="line">3582</span><br><span class="line">3583</span><br><span class="line">3584</span><br><span class="line">3585</span><br><span class="line">3586</span><br><span class="line">3587</span><br><span class="line">3588</span><br><span class="line">3589</span><br><span class="line">3590</span><br><span class="line">3591</span><br><span class="line">3592</span><br><span class="line">3593</span><br><span class="line">3594</span><br><span class="line">3595</span><br><span class="line">3596</span><br><span class="line">3597</span><br><span class="line">3598</span><br><span class="line">3599</span><br><span class="line">3600</span><br><span class="line">3601</span><br><span class="line">3602</span><br><span class="line">3603</span><br><span class="line">3604</span><br><span class="line">3605</span><br><span class="line">3606</span><br><span class="line">3607</span><br><span class="line">3608</span><br><span class="line">3609</span><br><span class="line">3610</span><br><span class="line">3611</span><br><span class="line">3612</span><br><span class="line">3613</span><br><span class="line">3614</span><br><span class="line">3615</span><br><span class="line">3616</span><br><span class="line">3617</span><br><span class="line">3618</span><br><span class="line">3619</span><br><span class="line">3620</span><br><span class="line">3621</span><br><span class="line">3622</span><br><span class="line">3623</span><br><span class="line">3624</span><br><span class="line">3625</span><br><span class="line">3626</span><br><span class="line">3627</span><br><span class="line">3628</span><br><span class="line">3629</span><br><span class="line">3630</span><br><span class="line">3631</span><br><span class="line">3632</span><br><span class="line">3633</span><br><span class="line">3634</span><br><span class="line">3635</span><br><span class="line">3636</span><br><span class="line">3637</span><br><span class="line">3638</span><br><span class="line">3639</span><br><span class="line">3640</span><br><span class="line">3641</span><br><span class="line">3642</span><br><span class="line">3643</span><br><span class="line">3644</span><br><span class="line">3645</span><br><span class="line">3646</span><br><span class="line">3647</span><br><span class="line">3648</span><br><span class="line">3649</span><br><span class="line">3650</span><br><span class="line">3651</span><br><span class="line">3652</span><br><span class="line">3653</span><br><span class="line">3654</span><br><span class="line">3655</span><br><span class="line">3656</span><br><span class="line">3657</span><br><span class="line">3658</span><br><span class="line">3659</span><br><span class="line">3660</span><br><span class="line">3661</span><br><span class="line">3662</span><br><span class="line">3663</span><br><span class="line">3664</span><br><span class="line">3665</span><br><span class="line">3666</span><br><span class="line">3667</span><br><span class="line">3668</span><br><span class="line">3669</span><br><span class="line">3670</span><br><span class="line">3671</span><br><span class="line">3672</span><br><span class="line">3673</span><br><span class="line">3674</span><br><span class="line">3675</span><br><span class="line">3676</span><br><span class="line">3677</span><br><span class="line">3678</span><br><span class="line">3679</span><br><span class="line">3680</span><br><span class="line">3681</span><br><span class="line">3682</span><br><span class="line">3683</span><br><span class="line">3684</span><br><span class="line">3685</span><br><span class="line">3686</span><br><span class="line">3687</span><br><span class="line">3688</span><br><span class="line">3689</span><br><span class="line">3690</span><br><span class="line">3691</span><br><span class="line">3692</span><br><span class="line">3693</span><br><span class="line">3694</span><br><span class="line">3695</span><br><span class="line">3696</span><br><span class="line">3697</span><br><span class="line">3698</span><br><span class="line">3699</span><br><span class="line">3700</span><br><span class="line">3701</span><br><span class="line">3702</span><br><span class="line">3703</span><br><span class="line">3704</span><br><span class="line">3705</span><br><span class="line">3706</span><br><span class="line">3707</span><br><span class="line">3708</span><br><span class="line">3709</span><br><span class="line">3710</span><br><span class="line">3711</span><br><span class="line">3712</span><br><span class="line">3713</span><br><span class="line">3714</span><br><span class="line">3715</span><br><span class="line">3716</span><br><span class="line">3717</span><br><span class="line">3718</span><br><span class="line">3719</span><br><span class="line">3720</span><br><span class="line">3721</span><br><span class="line">3722</span><br><span class="line">3723</span><br><span class="line">3724</span><br><span class="line">3725</span><br><span class="line">3726</span><br><span class="line">3727</span><br><span class="line">3728</span><br><span class="line">3729</span><br><span class="line">3730</span><br><span class="line">3731</span><br><span class="line">3732</span><br><span class="line">3733</span><br><span class="line">3734</span><br><span class="line">3735</span><br><span class="line">3736</span><br><span class="line">3737</span><br><span class="line">3738</span><br><span class="line">3739</span><br><span class="line">3740</span><br><span class="line">3741</span><br><span class="line">3742</span><br><span class="line">3743</span><br><span class="line">3744</span><br><span class="line">3745</span><br><span class="line">3746</span><br><span class="line">3747</span><br><span class="line">3748</span><br><span class="line">3749</span><br><span class="line">3750</span><br><span class="line">3751</span><br><span class="line">3752</span><br><span class="line">3753</span><br><span class="line">3754</span><br><span class="line">3755</span><br><span class="line">3756</span><br><span class="line">3757</span><br><span class="line">3758</span><br><span class="line">3759</span><br><span class="line">3760</span><br><span class="line">3761</span><br><span class="line">3762</span><br><span class="line">3763</span><br><span class="line">3764</span><br><span class="line">3765</span><br><span class="line">3766</span><br><span class="line">3767</span><br><span class="line">3768</span><br><span class="line">3769</span><br><span class="line">3770</span><br><span class="line">3771</span><br><span class="line">3772</span><br><span class="line">3773</span><br><span class="line">3774</span><br><span class="line">3775</span><br><span class="line">3776</span><br><span class="line">3777</span><br><span class="line">3778</span><br><span class="line">3779</span><br><span class="line">3780</span><br><span class="line">3781</span><br><span class="line">3782</span><br><span class="line">3783</span><br><span class="line">3784</span><br><span class="line">3785</span><br><span class="line">3786</span><br><span class="line">3787</span><br><span class="line">3788</span><br><span class="line">3789</span><br><span class="line">3790</span><br><span class="line">3791</span><br><span class="line">3792</span><br><span class="line">3793</span><br><span class="line">3794</span><br><span class="line">3795</span><br><span class="line">3796</span><br><span class="line">3797</span><br><span class="line">3798</span><br><span class="line">3799</span><br><span class="line">3800</span><br><span class="line">3801</span><br><span class="line">3802</span><br><span class="line">3803</span><br><span class="line">3804</span><br><span class="line">3805</span><br><span class="line">3806</span><br><span class="line">3807</span><br><span class="line">3808</span><br><span class="line">3809</span><br><span class="line">3810</span><br><span class="line">3811</span><br><span class="line">3812</span><br><span class="line">3813</span><br><span class="line">3814</span><br><span class="line">3815</span><br><span class="line">3816</span><br><span class="line">3817</span><br><span class="line">3818</span><br><span class="line">3819</span><br><span class="line">3820</span><br><span class="line">3821</span><br><span class="line">3822</span><br><span class="line">3823</span><br><span class="line">3824</span><br><span class="line">3825</span><br><span class="line">3826</span><br><span class="line">3827</span><br><span class="line">3828</span><br><span class="line">3829</span><br><span class="line">3830</span><br><span class="line">3831</span><br><span class="line">3832</span><br><span class="line">3833</span><br><span class="line">3834</span><br><span class="line">3835</span><br><span class="line">3836</span><br><span class="line">3837</span><br><span class="line">3838</span><br><span class="line">3839</span><br><span class="line">3840</span><br><span class="line">3841</span><br><span class="line">3842</span><br><span class="line">3843</span><br><span class="line">3844</span><br><span class="line">3845</span><br><span class="line">3846</span><br><span class="line">3847</span><br><span class="line">3848</span><br><span class="line">3849</span><br><span class="line">3850</span><br><span class="line">3851</span><br><span class="line">3852</span><br><span class="line">3853</span><br><span class="line">3854</span><br><span class="line">3855</span><br><span class="line">3856</span><br><span class="line">3857</span><br><span class="line">3858</span><br><span class="line">3859</span><br><span class="line">3860</span><br><span class="line">3861</span><br><span class="line">3862</span><br><span class="line">3863</span><br><span class="line">3864</span><br><span class="line">3865</span><br><span class="line">3866</span><br><span class="line">3867</span><br><span class="line">3868</span><br><span class="line">3869</span><br><span class="line">3870</span><br><span class="line">3871</span><br><span class="line">3872</span><br><span class="line">3873</span><br><span class="line">3874</span><br><span class="line">3875</span><br><span class="line">3876</span><br><span class="line">3877</span><br><span class="line">3878</span><br><span class="line">3879</span><br><span class="line">3880</span><br><span class="line">3881</span><br><span class="line">3882</span><br><span class="line">3883</span><br><span class="line">3884</span><br><span class="line">3885</span><br><span class="line">3886</span><br><span class="line">3887</span><br><span class="line">3888</span><br><span class="line">3889</span><br><span class="line">3890</span><br><span class="line">3891</span><br><span class="line">3892</span><br><span class="line">3893</span><br><span class="line">3894</span><br><span class="line">3895</span><br><span class="line">3896</span><br><span class="line">3897</span><br><span class="line">3898</span><br><span class="line">3899</span><br><span class="line">3900</span><br><span class="line">3901</span><br><span class="line">3902</span><br><span class="line">3903</span><br><span class="line">3904</span><br><span class="line">3905</span><br><span class="line">3906</span><br><span class="line">3907</span><br><span class="line">3908</span><br><span class="line">3909</span><br><span class="line">3910</span><br><span class="line">3911</span><br><span class="line">3912</span><br><span class="line">3913</span><br><span class="line">3914</span><br><span class="line">3915</span><br><span class="line">3916</span><br><span class="line">3917</span><br><span class="line">3918</span><br><span class="line">3919</span><br><span class="line">3920</span><br><span class="line">3921</span><br><span class="line">3922</span><br><span class="line">3923</span><br><span class="line">3924</span><br><span class="line">3925</span><br><span class="line">3926</span><br><span class="line">3927</span><br><span class="line">3928</span><br><span class="line">3929</span><br><span class="line">3930</span><br><span class="line">3931</span><br><span class="line">3932</span><br><span class="line">3933</span><br><span class="line">3934</span><br><span class="line">3935</span><br><span class="line">3936</span><br><span class="line">3937</span><br><span class="line">3938</span><br><span class="line">3939</span><br><span class="line">3940</span><br><span class="line">3941</span><br><span class="line">3942</span><br><span class="line">3943</span><br><span class="line">3944</span><br><span class="line">3945</span><br><span class="line">3946</span><br><span class="line">3947</span><br><span class="line">3948</span><br><span class="line">3949</span><br><span class="line">3950</span><br><span class="line">3951</span><br><span class="line">3952</span><br><span class="line">3953</span><br><span class="line">3954</span><br><span class="line">3955</span><br><span class="line">3956</span><br><span class="line">3957</span><br><span class="line">3958</span><br><span class="line">3959</span><br><span class="line">3960</span><br><span class="line">3961</span><br><span class="line">3962</span><br><span class="line">3963</span><br><span class="line">3964</span><br><span class="line">3965</span><br><span class="line">3966</span><br><span class="line">3967</span><br><span class="line">3968</span><br><span class="line">3969</span><br><span class="line">3970</span><br><span class="line">3971</span><br><span class="line">3972</span><br><span class="line">3973</span><br><span class="line">3974</span><br><span class="line">3975</span><br><span class="line">3976</span><br><span class="line">3977</span><br><span class="line">3978</span><br><span class="line">3979</span><br><span class="line">3980</span><br><span class="line">3981</span><br><span class="line">3982</span><br><span class="line">3983</span><br><span class="line">3984</span><br><span class="line">3985</span><br><span class="line">3986</span><br><span class="line">3987</span><br><span class="line">3988</span><br><span class="line">3989</span><br><span class="line">3990</span><br><span class="line">3991</span><br><span class="line">3992</span><br><span class="line">3993</span><br><span class="line">3994</span><br><span class="line">3995</span><br><span class="line">3996</span><br><span class="line">3997</span><br><span class="line">3998</span><br><span class="line">3999</span><br><span class="line">4000</span><br><span class="line">4001</span><br><span class="line">4002</span><br><span class="line">4003</span><br><span class="line">4004</span><br><span class="line">4005</span><br><span class="line">4006</span><br><span class="line">4007</span><br><span class="line">4008</span><br><span class="line">4009</span><br><span class="line">4010</span><br><span class="line">4011</span><br><span class="line">4012</span><br><span class="line">4013</span><br><span class="line">4014</span><br><span class="line">4015</span><br><span class="line">4016</span><br><span class="line">4017</span><br><span class="line">4018</span><br><span class="line">4019</span><br><span class="line">4020</span><br><span class="line">4021</span><br><span class="line">4022</span><br><span class="line">4023</span><br><span class="line">4024</span><br><span class="line">4025</span><br><span class="line">4026</span><br><span class="line">4027</span><br><span class="line">4028</span><br><span class="line">4029</span><br><span class="line">4030</span><br><span class="line">4031</span><br><span class="line">4032</span><br><span class="line">4033</span><br><span class="line">4034</span><br><span class="line">4035</span><br><span class="line">4036</span><br><span class="line">4037</span><br><span class="line">4038</span><br><span class="line">4039</span><br><span class="line">4040</span><br><span class="line">4041</span><br><span class="line">4042</span><br><span class="line">4043</span><br><span class="line">4044</span><br><span class="line">4045</span><br><span class="line">4046</span><br><span class="line">4047</span><br><span class="line">4048</span><br><span class="line">4049</span><br><span class="line">4050</span><br><span class="line">4051</span><br><span class="line">4052</span><br><span class="line">4053</span><br><span class="line">4054</span><br><span class="line">4055</span><br><span class="line">4056</span><br><span class="line">4057</span><br><span class="line">4058</span><br><span class="line">4059</span><br><span class="line">4060</span><br><span class="line">4061</span><br><span class="line">4062</span><br><span class="line">4063</span><br><span class="line">4064</span><br><span class="line">4065</span><br><span class="line">4066</span><br><span class="line">4067</span><br><span class="line">4068</span><br><span class="line">4069</span><br><span class="line">4070</span><br><span class="line">4071</span><br><span class="line">4072</span><br><span class="line">4073</span><br><span class="line">4074</span><br><span class="line">4075</span><br><span class="line">4076</span><br><span class="line">4077</span><br><span class="line">4078</span><br><span class="line">4079</span><br><span class="line">4080</span><br><span class="line">4081</span><br><span class="line">4082</span><br><span class="line">4083</span><br><span class="line">4084</span><br><span class="line">4085</span><br><span class="line">4086</span><br><span class="line">4087</span><br><span class="line">4088</span><br><span class="line">4089</span><br><span class="line">4090</span><br><span class="line">4091</span><br><span class="line">4092</span><br><span class="line">4093</span><br><span class="line">4094</span><br><span class="line">4095</span><br><span class="line">4096</span><br><span class="line">4097</span><br><span class="line">4098</span><br><span class="line">4099</span><br><span class="line">4100</span><br><span class="line">4101</span><br><span class="line">4102</span><br><span class="line">4103</span><br><span class="line">4104</span><br><span class="line">4105</span><br><span class="line">4106</span><br><span class="line">4107</span><br><span class="line">4108</span><br><span class="line">4109</span><br><span class="line">4110</span><br><span class="line">4111</span><br><span class="line">4112</span><br><span class="line">4113</span><br><span class="line">4114</span><br><span class="line">4115</span><br><span class="line">4116</span><br><span class="line">4117</span><br><span class="line">4118</span><br><span class="line">4119</span><br><span class="line">4120</span><br><span class="line">4121</span><br><span class="line">4122</span><br><span class="line">4123</span><br><span class="line">4124</span><br><span class="line">4125</span><br><span class="line">4126</span><br><span class="line">4127</span><br><span class="line">4128</span><br><span class="line">4129</span><br><span class="line">4130</span><br><span class="line">4131</span><br><span class="line">4132</span><br><span class="line">4133</span><br><span class="line">4134</span><br><span class="line">4135</span><br><span class="line">4136</span><br><span class="line">4137</span><br><span class="line">4138</span><br><span class="line">4139</span><br><span class="line">4140</span><br><span class="line">4141</span><br><span class="line">4142</span><br><span class="line">4143</span><br><span class="line">4144</span><br><span class="line">4145</span><br><span class="line">4146</span><br><span class="line">4147</span><br><span class="line">4148</span><br><span class="line">4149</span><br><span class="line">4150</span><br><span class="line">4151</span><br><span class="line">4152</span><br><span class="line">4153</span><br><span class="line">4154</span><br><span class="line">4155</span><br><span class="line">4156</span><br><span class="line">4157</span><br><span class="line">4158</span><br><span class="line">4159</span><br><span class="line">4160</span><br><span class="line">4161</span><br><span class="line">4162</span><br><span class="line">4163</span><br><span class="line">4164</span><br><span class="line">4165</span><br><span class="line">4166</span><br><span class="line">4167</span><br><span class="line">4168</span><br><span class="line">4169</span><br><span class="line">4170</span><br><span class="line">4171</span><br><span class="line">4172</span><br><span class="line">4173</span><br><span class="line">4174</span><br><span class="line">4175</span><br><span class="line">4176</span><br><span class="line">4177</span><br><span class="line">4178</span><br><span class="line">4179</span><br><span class="line">4180</span><br><span class="line">4181</span><br><span class="line">4182</span><br><span class="line">4183</span><br><span class="line">4184</span><br><span class="line">4185</span><br><span class="line">4186</span><br><span class="line">4187</span><br><span class="line">4188</span><br><span class="line">4189</span><br><span class="line">4190</span><br><span class="line">4191</span><br><span class="line">4192</span><br><span class="line">4193</span><br><span class="line">4194</span><br><span class="line">4195</span><br><span class="line">4196</span><br><span class="line">4197</span><br><span class="line">4198</span><br><span class="line">4199</span><br><span class="line">4200</span><br><span class="line">4201</span><br><span class="line">4202</span><br><span class="line">4203</span><br><span class="line">4204</span><br><span class="line">4205</span><br><span class="line">4206</span><br><span class="line">4207</span><br><span class="line">4208</span><br><span class="line">4209</span><br><span class="line">4210</span><br><span class="line">4211</span><br><span class="line">4212</span><br><span class="line">4213</span><br><span class="line">4214</span><br><span class="line">4215</span><br><span class="line">4216</span><br><span class="line">4217</span><br><span class="line">4218</span><br><span class="line">4219</span><br><span class="line">4220</span><br><span class="line">4221</span><br><span class="line">4222</span><br><span class="line">4223</span><br><span class="line">4224</span><br><span class="line">4225</span><br><span class="line">4226</span><br><span class="line">4227</span><br><span class="line">4228</span><br><span class="line">4229</span><br><span class="line">4230</span><br><span class="line">4231</span><br><span class="line">4232</span><br><span class="line">4233</span><br><span class="line">4234</span><br><span class="line">4235</span><br><span class="line">4236</span><br><span class="line">4237</span><br><span class="line">4238</span><br><span class="line">4239</span><br><span class="line">4240</span><br><span class="line">4241</span><br><span class="line">4242</span><br><span class="line">4243</span><br><span class="line">4244</span><br><span class="line">4245</span><br><span class="line">4246</span><br><span class="line">4247</span><br><span class="line">4248</span><br><span class="line">4249</span><br><span class="line">4250</span><br><span class="line">4251</span><br><span class="line">4252</span><br><span class="line">4253</span><br><span class="line">4254</span><br><span class="line">4255</span><br><span class="line">4256</span><br><span class="line">4257</span><br><span class="line">4258</span><br><span class="line">4259</span><br><span class="line">4260</span><br><span class="line">4261</span><br><span class="line">4262</span><br><span class="line">4263</span><br><span class="line">4264</span><br><span class="line">4265</span><br><span class="line">4266</span><br><span class="line">4267</span><br><span class="line">4268</span><br><span class="line">4269</span><br><span class="line">4270</span><br><span class="line">4271</span><br><span class="line">4272</span><br><span class="line">4273</span><br><span class="line">4274</span><br><span class="line">4275</span><br><span class="line">4276</span><br><span class="line">4277</span><br><span class="line">4278</span><br><span class="line">4279</span><br><span class="line">4280</span><br><span class="line">4281</span><br><span class="line">4282</span><br><span class="line">4283</span><br><span class="line">4284</span><br><span class="line">4285</span><br><span class="line">4286</span><br><span class="line">4287</span><br><span class="line">4288</span><br><span class="line">4289</span><br><span class="line">4290</span><br><span class="line">4291</span><br><span class="line">4292</span><br><span class="line">4293</span><br><span class="line">4294</span><br><span class="line">4295</span><br><span class="line">4296</span><br><span class="line">4297</span><br><span class="line">4298</span><br><span class="line">4299</span><br><span class="line">4300</span><br><span class="line">4301</span><br><span class="line">4302</span><br><span class="line">4303</span><br><span class="line">4304</span><br><span class="line">4305</span><br><span class="line">4306</span><br><span class="line">4307</span><br><span class="line">4308</span><br><span class="line">4309</span><br><span class="line">4310</span><br><span class="line">4311</span><br><span class="line">4312</span><br><span class="line">4313</span><br><span class="line">4314</span><br><span class="line">4315</span><br><span class="line">4316</span><br><span class="line">4317</span><br><span class="line">4318</span><br><span class="line">4319</span><br><span class="line">4320</span><br><span class="line">4321</span><br><span class="line">4322</span><br><span class="line">4323</span><br><span class="line">4324</span><br><span class="line">4325</span><br><span class="line">4326</span><br><span class="line">4327</span><br><span class="line">4328</span><br><span class="line">4329</span><br><span class="line">4330</span><br><span class="line">4331</span><br><span class="line">4332</span><br><span class="line">4333</span><br><span class="line">4334</span><br><span class="line">4335</span><br><span class="line">4336</span><br><span class="line">4337</span><br><span class="line">4338</span><br><span class="line">4339</span><br><span class="line">4340</span><br><span class="line">4341</span><br><span class="line">4342</span><br><span class="line">4343</span><br><span class="line">4344</span><br><span class="line">4345</span><br><span class="line">4346</span><br><span class="line">4347</span><br><span class="line">4348</span><br><span class="line">4349</span><br><span class="line">4350</span><br><span class="line">4351</span><br><span class="line">4352</span><br><span class="line">4353</span><br><span class="line">4354</span><br><span class="line">4355</span><br><span class="line">4356</span><br><span class="line">4357</span><br><span class="line">4358</span><br><span class="line">4359</span><br><span class="line">4360</span><br><span class="line">4361</span><br><span class="line">4362</span><br><span class="line">4363</span><br><span class="line">4364</span><br><span class="line">4365</span><br><span class="line">4366</span><br><span class="line">4367</span><br><span class="line">4368</span><br><span class="line">4369</span><br><span class="line">4370</span><br><span class="line">4371</span><br><span class="line">4372</span><br><span class="line">4373</span><br><span class="line">4374</span><br><span class="line">4375</span><br><span class="line">4376</span><br><span class="line">4377</span><br><span class="line">4378</span><br><span class="line">4379</span><br><span class="line">4380</span><br><span class="line">4381</span><br><span class="line">4382</span><br><span class="line">4383</span><br><span class="line">4384</span><br><span class="line">4385</span><br><span class="line">4386</span><br><span class="line">4387</span><br><span class="line">4388</span><br><span class="line">4389</span><br><span class="line">4390</span><br><span class="line">4391</span><br><span class="line">4392</span><br><span class="line">4393</span><br><span class="line">4394</span><br><span class="line">4395</span><br><span class="line">4396</span><br><span class="line">4397</span><br><span class="line">4398</span><br><span class="line">4399</span><br><span class="line">4400</span><br><span class="line">4401</span><br><span class="line">4402</span><br><span class="line">4403</span><br><span class="line">4404</span><br><span class="line">4405</span><br><span class="line">4406</span><br><span class="line">4407</span><br><span class="line">4408</span><br><span class="line">4409</span><br><span class="line">4410</span><br><span class="line">4411</span><br><span class="line">4412</span><br><span class="line">4413</span><br><span class="line">4414</span><br><span class="line">4415</span><br><span class="line">4416</span><br><span class="line">4417</span><br><span class="line">4418</span><br><span class="line">4419</span><br><span class="line">4420</span><br><span class="line">4421</span><br><span class="line">4422</span><br><span class="line">4423</span><br><span class="line">4424</span><br><span class="line">4425</span><br><span class="line">4426</span><br><span class="line">4427</span><br><span class="line">4428</span><br><span class="line">4429</span><br><span class="line">4430</span><br><span class="line">4431</span><br><span class="line">4432</span><br><span class="line">4433</span><br><span class="line">4434</span><br><span class="line">4435</span><br><span class="line">4436</span><br><span class="line">4437</span><br><span class="line">4438</span><br><span class="line">4439</span><br><span class="line">4440</span><br><span class="line">4441</span><br><span class="line">4442</span><br><span class="line">4443</span><br><span class="line">4444</span><br><span class="line">4445</span><br><span class="line">4446</span><br><span class="line">4447</span><br><span class="line">4448</span><br><span class="line">4449</span><br><span class="line">4450</span><br><span class="line">4451</span><br><span class="line">4452</span><br><span class="line">4453</span><br><span class="line">4454</span><br><span class="line">4455</span><br><span class="line">4456</span><br><span class="line">4457</span><br><span class="line">4458</span><br><span class="line">4459</span><br><span class="line">4460</span><br><span class="line">4461</span><br><span class="line">4462</span><br><span class="line">4463</span><br><span class="line">4464</span><br><span class="line">4465</span><br><span class="line">4466</span><br><span class="line">4467</span><br><span class="line">4468</span><br><span class="line">4469</span><br><span class="line">4470</span><br><span class="line">4471</span><br><span class="line">4472</span><br><span class="line">4473</span><br><span class="line">4474</span><br><span class="line">4475</span><br><span class="line">4476</span><br><span class="line">4477</span><br><span class="line">4478</span><br><span class="line">4479</span><br><span class="line">4480</span><br><span class="line">4481</span><br><span class="line">4482</span><br><span class="line">4483</span><br><span class="line">4484</span><br><span class="line">4485</span><br><span class="line">4486</span><br><span class="line">4487</span><br><span class="line">4488</span><br><span class="line">4489</span><br><span class="line">4490</span><br><span class="line">4491</span><br><span class="line">4492</span><br><span class="line">4493</span><br><span class="line">4494</span><br><span class="line">4495</span><br><span class="line">4496</span><br><span class="line">4497</span><br><span class="line">4498</span><br><span class="line">4499</span><br><span class="line">4500</span><br><span class="line">4501</span><br><span class="line">4502</span><br><span class="line">4503</span><br><span class="line">4504</span><br><span class="line">4505</span><br><span class="line">4506</span><br><span class="line">4507</span><br><span class="line">4508</span><br><span class="line">4509</span><br><span class="line">4510</span><br><span class="line">4511</span><br><span class="line">4512</span><br><span class="line">4513</span><br><span class="line">4514</span><br><span class="line">4515</span><br><span class="line">4516</span><br><span class="line">4517</span><br><span class="line">4518</span><br><span class="line">4519</span><br><span class="line">4520</span><br><span class="line">4521</span><br><span class="line">4522</span><br><span class="line">4523</span><br><span class="line">4524</span><br><span class="line">4525</span><br><span class="line">4526</span><br><span class="line">4527</span><br><span class="line">4528</span><br><span class="line">4529</span><br><span class="line">4530</span><br><span class="line">4531</span><br><span class="line">4532</span><br><span class="line">4533</span><br><span class="line">4534</span><br><span class="line">4535</span><br><span class="line">4536</span><br><span class="line">4537</span><br><span class="line">4538</span><br><span class="line">4539</span><br><span class="line">4540</span><br><span class="line">4541</span><br><span class="line">4542</span><br><span class="line">4543</span><br><span class="line">4544</span><br><span class="line">4545</span><br><span class="line">4546</span><br><span class="line">4547</span><br><span class="line">4548</span><br><span class="line">4549</span><br><span class="line">4550</span><br><span class="line">4551</span><br><span class="line">4552</span><br><span class="line">4553</span><br><span class="line">4554</span><br><span class="line">4555</span><br><span class="line">4556</span><br><span class="line">4557</span><br><span class="line">4558</span><br><span class="line">4559</span><br><span class="line">4560</span><br><span class="line">4561</span><br><span class="line">4562</span><br><span class="line">4563</span><br><span class="line">4564</span><br><span class="line">4565</span><br><span class="line">4566</span><br><span class="line">4567</span><br><span class="line">4568</span><br><span class="line">4569</span><br><span class="line">4570</span><br><span class="line">4571</span><br><span class="line">4572</span><br><span class="line">4573</span><br><span class="line">4574</span><br><span class="line">4575</span><br><span class="line">4576</span><br><span class="line">4577</span><br><span class="line">4578</span><br><span class="line">4579</span><br><span class="line">4580</span><br><span class="line">4581</span><br><span class="line">4582</span><br><span class="line">4583</span><br><span class="line">4584</span><br><span class="line">4585</span><br><span class="line">4586</span><br><span class="line">4587</span><br><span class="line">4588</span><br><span class="line">4589</span><br><span class="line">4590</span><br><span class="line">4591</span><br><span class="line">4592</span><br><span class="line">4593</span><br><span class="line">4594</span><br><span class="line">4595</span><br><span class="line">4596</span><br><span class="line">4597</span><br><span class="line">4598</span><br><span class="line">4599</span><br><span class="line">4600</span><br><span class="line">4601</span><br><span class="line">4602</span><br><span class="line">4603</span><br><span class="line">4604</span><br><span class="line">4605</span><br><span class="line">4606</span><br><span class="line">4607</span><br><span class="line">4608</span><br><span class="line">4609</span><br><span class="line">4610</span><br><span class="line">4611</span><br><span class="line">4612</span><br><span class="line">4613</span><br><span class="line">4614</span><br><span class="line">4615</span><br><span class="line">4616</span><br><span class="line">4617</span><br><span class="line">4618</span><br><span class="line">4619</span><br><span class="line">4620</span><br><span class="line">4621</span><br><span class="line">4622</span><br><span class="line">4623</span><br><span class="line">4624</span><br><span class="line">4625</span><br><span class="line">4626</span><br></pre></td><td class="code"><pre><span class="line">﻿<span class="comment">/*</span></span><br><span class="line"><span class="comment"> * Copyright (c) 2000-2003 Fabrice Bellard</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * This file is part of FFmpeg.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * FFmpeg is free software; you can redistribute it and/or</span></span><br><span class="line"><span class="comment"> * modify it under the terms of the GNU Lesser General Public</span></span><br><span class="line"><span class="comment"> * License as published by the Free Software Foundation; either</span></span><br><span class="line"><span class="comment"> * version 2.1 of the License, or (at your option) any later version.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * FFmpeg is distributed in the hope that it will be useful,</span></span><br><span class="line"><span class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</span></span><br><span class="line"><span class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU</span></span><br><span class="line"><span class="comment"> * Lesser General Public License for more details.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * You should have received a copy of the GNU Lesser General Public</span></span><br><span class="line"><span class="comment"> * License along with FFmpeg; if not, write to the Free Software</span></span><br><span class="line"><span class="comment"> * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @file</span></span><br><span class="line"><span class="comment"> * multimedia converter based on the FFmpeg libraries</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;config.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;ctype.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;math.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;errno.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;limits.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdatomic.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdint.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_IO_H</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;io.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_UNISTD_H</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavformat/avformat.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavdevice/avdevice.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libswresample/swresample.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/opt.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/channel_layout.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/parseutils.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/samplefmt.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/fifo.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/hwcontext.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/internal.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/intreadwrite.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/dict.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/display.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/mathematics.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/pixdesc.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/avstring.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/libm.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/imgutils.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/timestamp.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/bprint.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/time.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/thread.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/threadmessage.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavcodec/mathops.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavformat/os_support.h&quot;</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta"># <span class="meta-keyword">include</span> <span class="meta-string">&quot;libavfilter/avfilter.h&quot;</span></span></span><br><span class="line"><span class="meta"># <span class="meta-keyword">include</span> <span class="meta-string">&quot;libavfilter/buffersrc.h&quot;</span></span></span><br><span class="line"><span class="meta"># <span class="meta-keyword">include</span> <span class="meta-string">&quot;libavfilter/buffersink.h&quot;</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_SYS_RESOURCE_H</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;sys/time.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;sys/types.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;sys/resource.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">elif</span> HAVE_GETPROCESSTIMES</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;windows.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_GETPROCESSMEMORYINFO</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;windows.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;psapi.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_SETCONSOLECTRLHANDLER</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;windows.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_SYS_SELECT_H</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;sys/select.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_TERMIOS_H</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;fcntl.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;sys/ioctl.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;sys/time.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;termios.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">elif</span> HAVE_KBHIT</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;conio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;time.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;ffmpeg.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;cmdutils.h&quot;</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;libavutil/avassert.h&quot;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">char</span> program_name[] = <span class="string">&quot;ffmpeg&quot;</span>;       <span class="comment">// 程序名</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> program_birth_year = <span class="number">2000</span>;        <span class="comment">// 诞生年份</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> FILE *vstats_file;   <span class="comment">// 统计输出文件</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">char</span> *<span class="keyword">const</span> forced_keyframes_const_names[] = &#123;</span><br><span class="line">    <span class="string">&quot;n&quot;</span>,</span><br><span class="line">    <span class="string">&quot;n_forced&quot;</span>,</span><br><span class="line">    <span class="string">&quot;prev_forced_n&quot;</span>,</span><br><span class="line">    <span class="string">&quot;prev_forced_t&quot;</span>,</span><br><span class="line">    <span class="string">&quot;t&quot;</span>,</span><br><span class="line">    <span class="literal">NULL</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">BenchmarkTimeStamps</span> &#123;</span></span><br><span class="line">    <span class="keyword">int64_t</span> real_usec;</span><br><span class="line">    <span class="keyword">int64_t</span> user_usec;</span><br><span class="line">    <span class="keyword">int64_t</span> sys_usec;</span><br><span class="line">&#125; BenchmarkTimeStamps;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">do_video_stats</span><span class="params">(OutputStream *ost, <span class="keyword">int</span> frame_size)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">static</span> BenchmarkTimeStamps <span class="title">get_benchmark_time_stamps</span><span class="params">(<span class="keyword">void</span>)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int64_t</span> <span class="title">getmaxrss</span><span class="params">(<span class="keyword">void</span>)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">ifilter_has_all_input_formats</span><span class="params">(FilterGraph *fg)</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">int</span> run_as_daemon  = <span class="number">0</span>;  <span class="comment">// 后台运行</span></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">int</span> nb_frames_dup = <span class="number">0</span>;   <span class="comment">//</span></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">unsigned</span> dup_warning = <span class="number">1000</span>;</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">int</span> nb_frames_drop = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">int64_t</span> decode_error_stat[<span class="number">2</span>];</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">int</span> want_sdp = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> BenchmarkTimeStamps current_time;</span><br><span class="line">AVIOContext *progress_avio = <span class="literal">NULL</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">uint8_t</span> *subtitle_out;</span><br><span class="line"></span><br><span class="line">InputStream **input_streams = <span class="literal">NULL</span>; <span class="comment">// 输入流数组</span></span><br><span class="line"><span class="keyword">int</span>        nb_input_streams = <span class="number">0</span>;    <span class="comment">// 输出数量</span></span><br><span class="line">InputFile   **input_files   = <span class="literal">NULL</span>; <span class="comment">// 输入文件</span></span><br><span class="line"><span class="keyword">int</span>        nb_input_files   = <span class="number">0</span>;    <span class="comment">// 有多少个输入文件</span></span><br><span class="line"></span><br><span class="line">OutputStream **output_streams = <span class="literal">NULL</span>;</span><br><span class="line"><span class="keyword">int</span>         nb_output_streams = <span class="number">0</span>;  <span class="comment">// 输出数量</span></span><br><span class="line">OutputFile   **output_files   = <span class="literal">NULL</span>;</span><br><span class="line"><span class="keyword">int</span>         nb_output_files   = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">FilterGraph **filtergraphs;</span><br><span class="line"><span class="keyword">int</span>        nb_filtergraphs;     <span class="comment">// filter数量</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_TERMIOS_H</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* init terminal so that we can grab keys */</span></span><br><span class="line"><span class="keyword">static</span> <span class="class"><span class="keyword">struct</span> <span class="title">termios</span> <span class="title">oldtty</span>;</span></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">int</span> restore_tty;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_THREADS</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">free_input_threads</span><span class="params">(<span class="keyword">void</span>)</span></span>;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">term_exit_sigsafe</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_TERMIOS_H</span></span><br><span class="line">    <span class="keyword">if</span>(restore_tty)</span><br><span class="line">        tcsetattr (<span class="number">0</span>, TCSANOW, &amp;oldtty);</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">term_exit</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    av_log(<span class="literal">NULL</span>, AV_LOG_QUIET, <span class="string">&quot;%s&quot;</span>, <span class="string">&quot;&quot;</span>);</span><br><span class="line">    term_exit_sigsafe();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">volatile</span> <span class="keyword">int</span> received_sigterm = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">volatile</span> <span class="keyword">int</span> received_nb_signals = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">atomic_int</span> transcode_init_done = ATOMIC_VAR_INIT(<span class="number">0</span>);</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">volatile</span> <span class="keyword">int</span> ffmpeg_exited = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">int</span> main_return_code = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">void</span></span><br><span class="line">sigterm_handler(<span class="keyword">int</span> sig)</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">int</span> ret;</span><br><span class="line">    received_sigterm = sig;</span><br><span class="line">    received_nb_signals++;</span><br><span class="line">    term_exit_sigsafe();</span><br><span class="line">    <span class="keyword">if</span>(received_nb_signals &gt; <span class="number">3</span>) &#123;</span><br><span class="line">        ret = write(<span class="number">2</span><span class="comment">/*STDERR_FILENO*/</span>, <span class="string">&quot;Received &gt; 3 system signals, hard exiting\n&quot;</span>,</span><br><span class="line">                    <span class="built_in">strlen</span>(<span class="string">&quot;Received &gt; 3 system signals, hard exiting\n&quot;</span>));</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123; <span class="comment">/* Do nothing */</span> &#125;;</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">123</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_SETCONSOLECTRLHANDLER</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> BOOL WINAPI <span class="title">CtrlHandler</span><span class="params">(DWORD fdwCtrlType)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    av_log(<span class="literal">NULL</span>, AV_LOG_DEBUG, <span class="string">&quot;\nReceived windows signal %ld\n&quot;</span>, fdwCtrlType);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">switch</span> (fdwCtrlType)</span><br><span class="line">    &#123;</span><br><span class="line">    <span class="keyword">case</span> CTRL_C_EVENT:</span><br><span class="line">    <span class="keyword">case</span> CTRL_BREAK_EVENT:</span><br><span class="line">        sigterm_handler(SIGINT);</span><br><span class="line">        <span class="keyword">return</span> TRUE;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">case</span> CTRL_CLOSE_EVENT:</span><br><span class="line">    <span class="keyword">case</span> CTRL_LOGOFF_EVENT:</span><br><span class="line">    <span class="keyword">case</span> CTRL_SHUTDOWN_EVENT:</span><br><span class="line">        sigterm_handler(SIGTERM);</span><br><span class="line">        <span class="comment">/* Basically, with these 3 events, when we return from this method the</span></span><br><span class="line"><span class="comment">           process is hard terminated, so stall as long as we need to</span></span><br><span class="line"><span class="comment">           to try and let the main thread(s) clean up and gracefully terminate</span></span><br><span class="line"><span class="comment">           (we have at most 5 seconds, but should be done far before that). */</span></span><br><span class="line">        <span class="keyword">while</span> (!ffmpeg_exited) &#123;</span><br><span class="line">            Sleep(<span class="number">0</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> TRUE;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">default</span>:</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;Received unknown windows signal %ld\n&quot;</span>, fdwCtrlType);</span><br><span class="line">        <span class="keyword">return</span> FALSE;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">term_init</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_TERMIOS_H</span></span><br><span class="line">    <span class="keyword">if</span> (!run_as_daemon &amp;&amp; stdin_interaction) &#123;</span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">termios</span> <span class="title">tty</span>;</span></span><br><span class="line">        <span class="keyword">if</span> (tcgetattr (<span class="number">0</span>, &amp;tty) == <span class="number">0</span>) &#123;</span><br><span class="line">            oldtty = tty;</span><br><span class="line">            restore_tty = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">            tty.c_iflag &amp;= ~(IGNBRK|BRKINT|PARMRK|ISTRIP</span><br><span class="line">                             |INLCR|IGNCR|ICRNL|IXON);</span><br><span class="line">            tty.c_oflag |= OPOST;</span><br><span class="line">            tty.c_lflag &amp;= ~(ECHO|ECHONL|ICANON|IEXTEN);</span><br><span class="line">            tty.c_cflag &amp;= ~(CSIZE|PARENB);</span><br><span class="line">            tty.c_cflag |= CS8;</span><br><span class="line">            tty.c_cc[VMIN] = <span class="number">1</span>;</span><br><span class="line">            tty.c_cc[VTIME] = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">            tcsetattr (<span class="number">0</span>, TCSANOW, &amp;tty);</span><br><span class="line">        &#125;</span><br><span class="line">        signal(SIGQUIT, sigterm_handler); <span class="comment">/* Quit (POSIX).  */</span></span><br><span class="line">    &#125;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"></span><br><span class="line">    signal(SIGINT , sigterm_handler); <span class="comment">/* Interrupt (ANSI).    */</span></span><br><span class="line">    signal(SIGTERM, sigterm_handler); <span class="comment">/* Termination (ANSI).  */</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">ifdef</span> SIGXCPU</span></span><br><span class="line">    signal(SIGXCPU, sigterm_handler);</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">ifdef</span> SIGPIPE</span></span><br><span class="line">    signal(SIGPIPE, SIG_IGN); <span class="comment">/* Broken pipe (POSIX). */</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_SETCONSOLECTRLHANDLER</span></span><br><span class="line">    SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* read a key without blocking */</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">read_key</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">char</span> ch;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_TERMIOS_H</span></span><br><span class="line">    <span class="keyword">int</span> n = <span class="number">1</span>;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">timeval</span> <span class="title">tv</span>;</span></span><br><span class="line">    fd_set rfds;</span><br><span class="line"></span><br><span class="line">    FD_ZERO(&amp;rfds);</span><br><span class="line">    FD_SET(<span class="number">0</span>, &amp;rfds);</span><br><span class="line">    tv.tv_sec = <span class="number">0</span>;</span><br><span class="line">    tv.tv_usec = <span class="number">0</span>;</span><br><span class="line">    n = select(<span class="number">1</span>, &amp;rfds, <span class="literal">NULL</span>, <span class="literal">NULL</span>, &amp;tv);</span><br><span class="line">    <span class="keyword">if</span> (n &gt; <span class="number">0</span>) &#123;</span><br><span class="line">        n = read(<span class="number">0</span>, &amp;ch, <span class="number">1</span>);</span><br><span class="line">        <span class="keyword">if</span> (n == <span class="number">1</span>)</span><br><span class="line">            <span class="keyword">return</span> ch;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> n;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">elif</span> HAVE_KBHIT</span></span><br><span class="line"><span class="meta">#    <span class="meta-keyword">if</span> HAVE_PEEKNAMEDPIPE</span></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> is_pipe;</span><br><span class="line">    <span class="keyword">static</span> HANDLE input_handle;</span><br><span class="line">    DWORD dw, nchars;</span><br><span class="line">    <span class="keyword">if</span>(!input_handle)&#123;</span><br><span class="line">        input_handle = GetStdHandle(STD_INPUT_HANDLE);</span><br><span class="line">        is_pipe = !GetConsoleMode(input_handle, &amp;dw);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (is_pipe) &#123;</span><br><span class="line">        <span class="comment">/* When running under a GUI, you will end here. */</span></span><br><span class="line">        <span class="keyword">if</span> (!PeekNamedPipe(input_handle, <span class="literal">NULL</span>, <span class="number">0</span>, <span class="literal">NULL</span>, &amp;nchars, <span class="literal">NULL</span>)) &#123;</span><br><span class="line">            <span class="comment">// input pipe may have been closed by the program that ran ffmpeg</span></span><br><span class="line">            <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//Read it</span></span><br><span class="line">        <span class="keyword">if</span>(nchars != <span class="number">0</span>) &#123;</span><br><span class="line">            read(<span class="number">0</span>, &amp;ch, <span class="number">1</span>);</span><br><span class="line">            <span class="keyword">return</span> ch;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="meta">#    <span class="meta-keyword">endif</span></span></span><br><span class="line">    <span class="keyword">if</span>(kbhit())</span><br><span class="line">        <span class="keyword">return</span>(getch());</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">decode_interrupt_cb</span><span class="params">(<span class="keyword">void</span> *ctx)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> received_nb_signals &gt; atomic_load(&amp;transcode_init_done);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> AVIOInterruptCB int_cb = &#123; decode_interrupt_cb, <span class="literal">NULL</span> &#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">ffmpeg_cleanup</span><span class="params">(<span class="keyword">int</span> ret)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i, j;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (do_benchmark) &#123;</span><br><span class="line">        <span class="keyword">int</span> maxrss = getmaxrss() / <span class="number">1024</span>;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;bench: maxrss=%ikB\n&quot;</span>, maxrss);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_filtergraphs; i++) &#123;</span><br><span class="line">        FilterGraph *fg = filtergraphs[i];</span><br><span class="line">        avfilter_graph_free(&amp;fg-&gt;graph);</span><br><span class="line">        <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; fg-&gt;nb_inputs; j++) &#123;</span><br><span class="line">            <span class="keyword">while</span> (av_fifo_size(fg-&gt;inputs[j]-&gt;frame_queue)) &#123;</span><br><span class="line">                AVFrame *frame;</span><br><span class="line">                av_fifo_generic_read(fg-&gt;inputs[j]-&gt;frame_queue, &amp;frame,</span><br><span class="line">                                     <span class="keyword">sizeof</span>(frame), <span class="literal">NULL</span>);</span><br><span class="line">                av_frame_free(&amp;frame);</span><br><span class="line">            &#125;</span><br><span class="line">            av_fifo_freep(&amp;fg-&gt;inputs[j]-&gt;frame_queue);</span><br><span class="line">            av_buffer_unref(&amp;fg-&gt;inputs[j]-&gt;hw_frames_ctx);</span><br><span class="line">            av_freep(&amp;fg-&gt;inputs[j]-&gt;name);</span><br><span class="line">            av_freep(&amp;fg-&gt;inputs[j]);</span><br><span class="line">        &#125;</span><br><span class="line">        av_freep(&amp;fg-&gt;inputs);</span><br><span class="line">        <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; fg-&gt;nb_outputs; j++) &#123;</span><br><span class="line">            av_freep(&amp;fg-&gt;outputs[j]-&gt;name);</span><br><span class="line">            av_freep(&amp;fg-&gt;outputs[j]-&gt;formats);</span><br><span class="line">            av_freep(&amp;fg-&gt;outputs[j]-&gt;channel_layouts);</span><br><span class="line">            av_freep(&amp;fg-&gt;outputs[j]-&gt;sample_rates);</span><br><span class="line">            av_freep(&amp;fg-&gt;outputs[j]);</span><br><span class="line">        &#125;</span><br><span class="line">        av_freep(&amp;fg-&gt;outputs);</span><br><span class="line">        av_freep(&amp;fg-&gt;graph_desc);</span><br><span class="line"></span><br><span class="line">        av_freep(&amp;filtergraphs[i]);</span><br><span class="line">    &#125;</span><br><span class="line">    av_freep(&amp;filtergraphs);</span><br><span class="line"></span><br><span class="line">    av_freep(&amp;subtitle_out);</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* close files */</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_files; i++) &#123;</span><br><span class="line">        OutputFile *of = output_files[i];</span><br><span class="line">        AVFormatContext *s;</span><br><span class="line">        <span class="keyword">if</span> (!of)</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        s = of-&gt;ctx;</span><br><span class="line">        <span class="keyword">if</span> (s &amp;&amp; s-&gt;oformat &amp;&amp; !(s-&gt;oformat-&gt;flags &amp; AVFMT_NOFILE))</span><br><span class="line">            avio_closep(&amp;s-&gt;pb);</span><br><span class="line">        avformat_free_context(s);</span><br><span class="line">        av_dict_free(&amp;of-&gt;opts);</span><br><span class="line"></span><br><span class="line">        av_freep(&amp;output_files[i]);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_streams; i++) &#123;</span><br><span class="line">        OutputStream *ost = output_streams[i];</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!ost)</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; ost-&gt;nb_bitstream_filters; j++)</span><br><span class="line">            av_bsf_free(&amp;ost-&gt;bsf_ctx[j]);</span><br><span class="line">        av_freep(&amp;ost-&gt;bsf_ctx);</span><br><span class="line"></span><br><span class="line">        av_frame_free(&amp;ost-&gt;filtered_frame);</span><br><span class="line">        av_frame_free(&amp;ost-&gt;last_frame);</span><br><span class="line">        av_dict_free(&amp;ost-&gt;encoder_opts);</span><br><span class="line"></span><br><span class="line">        av_freep(&amp;ost-&gt;forced_keyframes);</span><br><span class="line">        av_expr_free(ost-&gt;forced_keyframes_pexpr);</span><br><span class="line">        av_freep(&amp;ost-&gt;avfilter);</span><br><span class="line">        av_freep(&amp;ost-&gt;logfile_prefix);</span><br><span class="line"></span><br><span class="line">        av_freep(&amp;ost-&gt;audio_channels_map);</span><br><span class="line">        ost-&gt;audio_channels_mapped = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">        av_dict_free(&amp;ost-&gt;sws_dict);</span><br><span class="line"></span><br><span class="line">        avcodec_free_context(&amp;ost-&gt;enc_ctx);</span><br><span class="line">        avcodec_parameters_free(&amp;ost-&gt;ref_par);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;muxing_queue) &#123;</span><br><span class="line">            <span class="keyword">while</span> (av_fifo_size(ost-&gt;muxing_queue)) &#123;</span><br><span class="line">                AVPacket pkt;</span><br><span class="line">                av_fifo_generic_read(ost-&gt;muxing_queue, &amp;pkt, <span class="keyword">sizeof</span>(pkt), <span class="literal">NULL</span>);</span><br><span class="line">                av_packet_unref(&amp;pkt);</span><br><span class="line">            &#125;</span><br><span class="line">            av_fifo_freep(&amp;ost-&gt;muxing_queue);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        av_freep(&amp;output_streams[i]);</span><br><span class="line">    &#125;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_THREADS</span></span><br><span class="line">    free_input_threads();</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_input_files; i++) &#123;</span><br><span class="line">        avformat_close_input(&amp;input_files[i]-&gt;ctx);</span><br><span class="line">        av_freep(&amp;input_files[i]);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_input_streams; i++) &#123;</span><br><span class="line">        InputStream *ist = input_streams[i];</span><br><span class="line"></span><br><span class="line">        av_frame_free(&amp;ist-&gt;decoded_frame);</span><br><span class="line">        av_frame_free(&amp;ist-&gt;filter_frame);</span><br><span class="line">        av_dict_free(&amp;ist-&gt;decoder_opts);</span><br><span class="line">        av_freep(&amp;ist-&gt;filters);</span><br><span class="line">        av_freep(&amp;ist-&gt;hwaccel_device);</span><br><span class="line">        av_freep(&amp;ist-&gt;dts_buffer);</span><br><span class="line"></span><br><span class="line">        avcodec_free_context(&amp;ist-&gt;dec_ctx);</span><br><span class="line"></span><br><span class="line">        av_freep(&amp;input_streams[i]);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (vstats_file) &#123;</span><br><span class="line">        <span class="keyword">if</span> (fclose(vstats_file))</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_ERROR,</span><br><span class="line">                   <span class="string">&quot;Error closing vstats file, loss of information possible: %s\n&quot;</span>,</span><br><span class="line">                   av_err2str(AVERROR(errno)));</span><br><span class="line">    &#125;</span><br><span class="line">    av_freep(&amp;vstats_filename);</span><br><span class="line"></span><br><span class="line">    av_freep(&amp;input_streams);</span><br><span class="line">    av_freep(&amp;input_files);</span><br><span class="line">    av_freep(&amp;output_streams);</span><br><span class="line">    av_freep(&amp;output_files);</span><br><span class="line"></span><br><span class="line">    uninit_opts();</span><br><span class="line"></span><br><span class="line">    avformat_network_deinit();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (received_sigterm) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;Exiting normally, received signal %d.\n&quot;</span>,</span><br><span class="line">               (<span class="keyword">int</span>) received_sigterm);</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (ret &amp;&amp; atomic_load(&amp;transcode_init_done)) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;Conversion failed!\n&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    term_exit();</span><br><span class="line">    ffmpeg_exited = <span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">remove_avoptions</span><span class="params">(AVDictionary **a, AVDictionary *b)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    AVDictionaryEntry *t = <span class="literal">NULL</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span> ((t = av_dict_get(b, <span class="string">&quot;&quot;</span>, t, AV_DICT_IGNORE_SUFFIX))) &#123;</span><br><span class="line">        av_dict_set(a, t-&gt;key, <span class="literal">NULL</span>, AV_DICT_MATCH_CASE);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">assert_avoptions</span><span class="params">(AVDictionary *m)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    AVDictionaryEntry *t;</span><br><span class="line">    <span class="keyword">if</span> ((t = av_dict_get(m, <span class="string">&quot;&quot;</span>, <span class="literal">NULL</span>, AV_DICT_IGNORE_SUFFIX))) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_FATAL, <span class="string">&quot;Option %s not found.\n&quot;</span>, t-&gt;key);</span><br><span class="line">        exit_program(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">abort_codec_experimental</span><span class="params">(AVCodec *c, <span class="keyword">int</span> encoder)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    exit_program(<span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">update_benchmark</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span> *fmt, ...)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (do_benchmark_all) &#123;</span><br><span class="line">        BenchmarkTimeStamps t = get_benchmark_time_stamps();</span><br><span class="line">        va_list va;</span><br><span class="line">        <span class="keyword">char</span> buf[<span class="number">1024</span>];</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (fmt) &#123;</span><br><span class="line">            va_start(va, fmt);</span><br><span class="line">            vsnprintf(buf, <span class="keyword">sizeof</span>(buf), fmt, va);</span><br><span class="line">            va_end(va);</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_INFO,</span><br><span class="line">                   <span class="string">&quot;bench: %8&quot;</span> PRIu64 <span class="string">&quot; user %8&quot;</span> PRIu64 <span class="string">&quot; sys %8&quot;</span> PRIu64 <span class="string">&quot; real %s \n&quot;</span>,</span><br><span class="line">                   t.user_usec - current_time.user_usec,</span><br><span class="line">                   t.sys_usec - current_time.sys_usec,</span><br><span class="line">                   t.real_usec - current_time.real_usec, buf);</span><br><span class="line">        &#125;</span><br><span class="line">        current_time = t;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">close_all_output_streams</span><span class="params">(OutputStream *ost, OSTFinished this_stream, OSTFinished others)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i;</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_streams; i++) &#123;</span><br><span class="line">        OutputStream *ost2 = output_streams[i];</span><br><span class="line">        ost2-&gt;finished |= ost == ost2 ? this_stream : others;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">write_packet</span><span class="params">(OutputFile *of, AVPacket *pkt, OutputStream *ost, <span class="keyword">int</span> unqueue)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    AVFormatContext *s = of-&gt;ctx;</span><br><span class="line">    AVStream *st = ost-&gt;st;</span><br><span class="line">    <span class="keyword">int</span> ret;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">     * Audio encoders may split the packets --  #frames in != #packets out.</span></span><br><span class="line"><span class="comment">     * But there is no reordering, so we can limit the number of output packets</span></span><br><span class="line"><span class="comment">     * by simply dropping them here.</span></span><br><span class="line"><span class="comment">     * Counting encoded video frames needs to be done separately because of</span></span><br><span class="line"><span class="comment">     * reordering, see do_video_out().</span></span><br><span class="line"><span class="comment">     * Do not count the packet when unqueued because it has been counted when queued.</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">if</span> (!(st-&gt;codecpar-&gt;codec_type == AVMEDIA_TYPE_VIDEO &amp;&amp; ost-&gt;encoding_needed) &amp;&amp; !unqueue) &#123;</span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;frame_number &gt;= ost-&gt;max_frames) &#123;</span><br><span class="line">            av_packet_unref(pkt);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        ost-&gt;frame_number++;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!of-&gt;header_written) &#123;  <span class="comment">// 头部还没有写入</span></span><br><span class="line">        AVPacket tmp_pkt = &#123;<span class="number">0</span>&#125;;</span><br><span class="line">        <span class="comment">/* the muxer is not initialized yet, buffer the packet */</span></span><br><span class="line">        <span class="keyword">if</span> (!av_fifo_space(ost-&gt;muxing_queue)) &#123;</span><br><span class="line">            <span class="keyword">int</span> new_size = FFMIN(<span class="number">2</span> * av_fifo_size(ost-&gt;muxing_queue),</span><br><span class="line">                                 ost-&gt;max_muxing_queue_size);</span><br><span class="line">            <span class="keyword">if</span> (new_size &lt;= av_fifo_size(ost-&gt;muxing_queue)) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_ERROR,</span><br><span class="line">                       <span class="string">&quot;Too many packets buffered for output stream %d:%d.\n&quot;</span>,</span><br><span class="line">                       ost-&gt;file_index, ost-&gt;st-&gt;index);</span><br><span class="line">                exit_program(<span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            ret = av_fifo_realloc2(ost-&gt;muxing_queue, new_size);</span><br><span class="line">            <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">                exit_program(<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        ret = av_packet_make_refcounted(pkt);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">            exit_program(<span class="number">1</span>);</span><br><span class="line">        av_packet_move_ref(&amp;tmp_pkt, pkt);</span><br><span class="line">        av_fifo_generic_write(ost-&gt;muxing_queue, &amp;tmp_pkt, <span class="keyword">sizeof</span>(tmp_pkt), <span class="literal">NULL</span>);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> ((st-&gt;codecpar-&gt;codec_type == AVMEDIA_TYPE_VIDEO &amp;&amp; video_sync_method == VSYNC_DROP) ||</span><br><span class="line">        (st-&gt;codecpar-&gt;codec_type == AVMEDIA_TYPE_AUDIO &amp;&amp; audio_sync_method &lt; <span class="number">0</span>))</span><br><span class="line">        pkt-&gt;pts = pkt-&gt;dts = AV_NOPTS_VALUE;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (st-&gt;codecpar-&gt;codec_type == AVMEDIA_TYPE_VIDEO) &#123;</span><br><span class="line">        <span class="keyword">int</span> i;</span><br><span class="line">        <span class="keyword">uint8_t</span> *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS,</span><br><span class="line">                                              <span class="literal">NULL</span>);</span><br><span class="line">        ost-&gt;quality = sd ? AV_RL32(sd) : <span class="number">-1</span>;</span><br><span class="line">        ost-&gt;pict_type = sd ? sd[<span class="number">4</span>] : AV_PICTURE_TYPE_NONE;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (i = <span class="number">0</span>; i&lt;FF_ARRAY_ELEMS(ost-&gt;error); i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (sd &amp;&amp; i &lt; sd[<span class="number">5</span>])</span><br><span class="line">                ost-&gt;error[i] = AV_RL64(sd + <span class="number">8</span> + <span class="number">8</span>*i);</span><br><span class="line">            <span class="keyword">else</span></span><br><span class="line">                ost-&gt;error[i] = <span class="number">-1</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;frame_rate.num &amp;&amp; ost-&gt;is_cfr) &#123;</span><br><span class="line">            <span class="keyword">if</span> (pkt-&gt;duration &gt; <span class="number">0</span>)</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_WARNING, <span class="string">&quot;Overriding packet duration by frame rate, this should not happen\n&quot;</span>);</span><br><span class="line">            pkt-&gt;duration = av_rescale_q(<span class="number">1</span>, av_inv_q(ost-&gt;frame_rate),</span><br><span class="line">                                         ost-&gt;mux_timebase);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 将pkt 从ost-&gt;mux_timebase转成ost-&gt;st-&gt;time_base</span></span><br><span class="line">    <span class="comment">// 即是从编码器转成 输出流的time_base</span></span><br><span class="line">    av_packet_rescale_ts(pkt, ost-&gt;mux_timebase, ost-&gt;st-&gt;time_base);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!(s-&gt;oformat-&gt;flags &amp; AVFMT_NOTIMESTAMPS)) &#123;</span><br><span class="line">        <span class="keyword">if</span> (pkt-&gt;dts != AV_NOPTS_VALUE &amp;&amp;</span><br><span class="line">            pkt-&gt;pts != AV_NOPTS_VALUE &amp;&amp;</span><br><span class="line">            pkt-&gt;dts &gt; pkt-&gt;pts) &#123;</span><br><span class="line">            av_log(s, AV_LOG_WARNING, <span class="string">&quot;Invalid DTS: %&quot;</span>PRId64<span class="string">&quot; PTS: %&quot;</span>PRId64<span class="string">&quot; in output stream %d:%d, replacing by guess\n&quot;</span>,</span><br><span class="line">                   pkt-&gt;dts, pkt-&gt;pts,</span><br><span class="line">                   ost-&gt;file_index, ost-&gt;st-&gt;index);</span><br><span class="line">            pkt-&gt;pts =</span><br><span class="line">            pkt-&gt;dts = pkt-&gt;pts + pkt-&gt;dts + ost-&gt;last_mux_dts + <span class="number">1</span></span><br><span class="line">                     - FFMIN3(pkt-&gt;pts, pkt-&gt;dts, ost-&gt;last_mux_dts + <span class="number">1</span>)</span><br><span class="line">                     - FFMAX3(pkt-&gt;pts, pkt-&gt;dts, ost-&gt;last_mux_dts + <span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> ((st-&gt;codecpar-&gt;codec_type == AVMEDIA_TYPE_AUDIO || st-&gt;codecpar-&gt;codec_type == AVMEDIA_TYPE_VIDEO || st-&gt;codecpar-&gt;codec_type == AVMEDIA_TYPE_SUBTITLE) &amp;&amp;</span><br><span class="line">            pkt-&gt;dts != AV_NOPTS_VALUE &amp;&amp;</span><br><span class="line">            !(st-&gt;codecpar-&gt;codec_id == AV_CODEC_ID_VP9 &amp;&amp; ost-&gt;stream_copy) &amp;&amp;</span><br><span class="line">            ost-&gt;last_mux_dts != AV_NOPTS_VALUE) &#123;</span><br><span class="line">            <span class="keyword">int64_t</span> max = ost-&gt;last_mux_dts + !(s-&gt;oformat-&gt;flags &amp; AVFMT_TS_NONSTRICT);</span><br><span class="line">            <span class="keyword">if</span> (pkt-&gt;dts &lt; max) &#123;</span><br><span class="line">                <span class="keyword">int</span> loglevel = max - pkt-&gt;dts &gt; <span class="number">2</span> || st-&gt;codecpar-&gt;codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;</span><br><span class="line">                av_log(s, loglevel, <span class="string">&quot;Non-monotonous DTS in output stream &quot;</span></span><br><span class="line">                       <span class="string">&quot;%d:%d; previous: %&quot;</span>PRId64<span class="string">&quot;, current: %&quot;</span>PRId64<span class="string">&quot;; &quot;</span>,</span><br><span class="line">                       ost-&gt;file_index, ost-&gt;st-&gt;index, ost-&gt;last_mux_dts, pkt-&gt;dts);</span><br><span class="line">                <span class="keyword">if</span> (exit_on_error) &#123;</span><br><span class="line">                    av_log(<span class="literal">NULL</span>, AV_LOG_FATAL, <span class="string">&quot;aborting.\n&quot;</span>);</span><br><span class="line">                    exit_program(<span class="number">1</span>);</span><br><span class="line">                &#125;</span><br><span class="line">                av_log(s, loglevel, <span class="string">&quot;changing to %&quot;</span>PRId64<span class="string">&quot;. This may result &quot;</span></span><br><span class="line">                       <span class="string">&quot;in incorrect timestamps in the output file.\n&quot;</span>,</span><br><span class="line">                       max);</span><br><span class="line">                <span class="keyword">if</span> (pkt-&gt;pts &gt;= pkt-&gt;dts)</span><br><span class="line">                    pkt-&gt;pts = FFMAX(pkt-&gt;pts, max);</span><br><span class="line">                pkt-&gt;dts = max;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    ost-&gt;last_mux_dts = pkt-&gt;dts;</span><br><span class="line"></span><br><span class="line">    ost-&gt;data_size += pkt-&gt;size;</span><br><span class="line">    ost-&gt;packets_written++;</span><br><span class="line"></span><br><span class="line">    pkt-&gt;stream_index = ost-&gt;index;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (debug_ts) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;muxer &lt;- type:%s &quot;</span></span><br><span class="line">                <span class="string">&quot;pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s size:%d\n&quot;</span>,</span><br><span class="line">                av_get_media_type_string(ost-&gt;enc_ctx-&gt;codec_type),</span><br><span class="line">                av_ts2str(pkt-&gt;pts), av_ts2timestr(pkt-&gt;pts, &amp;ost-&gt;st-&gt;time_base),</span><br><span class="line">                av_ts2str(pkt-&gt;dts), av_ts2timestr(pkt-&gt;dts, &amp;ost-&gt;st-&gt;time_base),</span><br><span class="line">                pkt-&gt;size</span><br><span class="line">              );</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    ret = av_interleaved_write_frame(s, pkt);   <span class="comment">// 真正写入</span></span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">        print_error(<span class="string">&quot;av_interleaved_write_frame()&quot;</span>, ret);</span><br><span class="line">        main_return_code = <span class="number">1</span>;</span><br><span class="line">        close_all_output_streams(ost, MUXER_FINISHED | ENCODER_FINISHED, ENCODER_FINISHED);</span><br><span class="line">    &#125;</span><br><span class="line">    av_packet_unref(pkt);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">close_output_stream</span><span class="params">(OutputStream *ost)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    OutputFile *of = output_files[ost-&gt;file_index];</span><br><span class="line"></span><br><span class="line">    ost-&gt;finished |= ENCODER_FINISHED;</span><br><span class="line">    <span class="keyword">if</span> (of-&gt;shortest) &#123;</span><br><span class="line">        <span class="comment">// enc_ctx-&gt;time_base转成微妙</span></span><br><span class="line">        <span class="keyword">int64_t</span> end = av_rescale_q(ost-&gt;sync_opts - ost-&gt;first_pts, ost-&gt;enc_ctx-&gt;time_base, AV_TIME_BASE_Q);</span><br><span class="line">        of-&gt;recording_time = FFMIN(of-&gt;recording_time, end);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * Send a single packet to the output, applying any bitstream filters</span></span><br><span class="line"><span class="comment"> * associated with the output stream.  This may result in any number</span></span><br><span class="line"><span class="comment"> * of packets actually being written, depending on what bitstream</span></span><br><span class="line"><span class="comment"> * filters are applied.  The supplied packet is consumed and will be</span></span><br><span class="line"><span class="comment"> * blank (as if newly-allocated) when this function returns.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * If eof is set, instead indicate EOF to all bitstream filters and</span></span><br><span class="line"><span class="comment"> * therefore flush any delayed packets to the output.  A blank packet</span></span><br><span class="line"><span class="comment"> * must be supplied in this case.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @brief output_packet 输出packet</span></span><br><span class="line"><span class="comment"> * @param of    属于哪个输出文件</span></span><br><span class="line"><span class="comment"> * @param pkt   输出包</span></span><br><span class="line"><span class="comment"> * @param ost   属于哪个输出流</span></span><br><span class="line"><span class="comment"> * @param eof   是否结束</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">output_packet</span><span class="params">(OutputFile *of, AVPacket *pkt,</span></span></span><br><span class="line"><span class="function"><span class="params">                          OutputStream *ost, <span class="keyword">int</span> eof)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> ret = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* apply the output bitstream filters, if any */</span></span><br><span class="line">    <span class="keyword">if</span> (ost-&gt;nb_bitstream_filters) &#123;    <span class="comment">// 需要bitstream filters</span></span><br><span class="line">        <span class="keyword">int</span> idx;</span><br><span class="line"></span><br><span class="line">        ret = av_bsf_send_packet(ost-&gt;bsf_ctx[<span class="number">0</span>], eof ? <span class="literal">NULL</span> : pkt);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">goto</span> finish;</span><br><span class="line"></span><br><span class="line">        eof = <span class="number">0</span>;</span><br><span class="line">        idx = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (idx) &#123;</span><br><span class="line">            <span class="comment">/* get a packet from the previous filter up the chain */</span></span><br><span class="line">            ret = av_bsf_receive_packet(ost-&gt;bsf_ctx[idx - <span class="number">1</span>], pkt);</span><br><span class="line">            <span class="keyword">if</span> (ret == AVERROR(EAGAIN)) &#123;</span><br><span class="line">                ret = <span class="number">0</span>;</span><br><span class="line">                idx--;</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (ret == AVERROR_EOF) &#123;</span><br><span class="line">                eof = <span class="number">1</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">                <span class="keyword">goto</span> finish;</span><br><span class="line"></span><br><span class="line">            <span class="comment">/* send it to the next filter down the chain or to the muxer */</span></span><br><span class="line">            <span class="keyword">if</span> (idx &lt; ost-&gt;nb_bitstream_filters) &#123;</span><br><span class="line">                ret = av_bsf_send_packet(ost-&gt;bsf_ctx[idx], eof ? <span class="literal">NULL</span> : pkt);</span><br><span class="line">                <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">                    <span class="keyword">goto</span> finish;</span><br><span class="line">                idx++;</span><br><span class="line">                eof = <span class="number">0</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (eof)</span><br><span class="line">                <span class="keyword">goto</span> finish;</span><br><span class="line">            <span class="keyword">else</span></span><br><span class="line">                write_packet(of, pkt, ost, <span class="number">0</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (!eof)</span><br><span class="line">        write_packet(of, pkt, ost, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">finish:</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span> &amp;&amp; ret != AVERROR_EOF) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;Error applying bitstream filters to an output &quot;</span></span><br><span class="line">               <span class="string">&quot;packet for stream #%d:%d.\n&quot;</span>, ost-&gt;file_index, ost-&gt;index);</span><br><span class="line">        <span class="keyword">if</span>(exit_on_error)</span><br><span class="line">            exit_program(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">check_recording_time</span><span class="params">(OutputStream *ost)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    OutputFile *of = output_files[ost-&gt;file_index];</span><br><span class="line">    <span class="comment">//av_compare_ts - 1 if `ts_a` is after `ts_b`</span></span><br><span class="line">    <span class="keyword">if</span> (of-&gt;recording_time != INT64_MAX &amp;&amp;</span><br><span class="line">        av_compare_ts(ost-&gt;sync_opts - ost-&gt;first_pts, ost-&gt;enc_ctx-&gt;time_base, of-&gt;recording_time,</span><br><span class="line">                      AV_TIME_BASE_Q) &gt;= <span class="number">0</span>) &#123;</span><br><span class="line">        close_output_stream(ost);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">do_audio_out</span><span class="params">(OutputFile *of, OutputStream *ost,</span></span></span><br><span class="line"><span class="function"><span class="params">                         AVFrame *frame)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    AVCodecContext *enc = ost-&gt;enc_ctx;</span><br><span class="line">    AVPacket pkt;</span><br><span class="line">    <span class="keyword">int</span> ret;</span><br><span class="line"></span><br><span class="line">    av_init_packet(&amp;pkt);</span><br><span class="line">    pkt.data = <span class="literal">NULL</span>;</span><br><span class="line">    pkt.size = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!check_recording_time(ost))</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (frame-&gt;pts == AV_NOPTS_VALUE || audio_sync_method &lt; <span class="number">0</span>)</span><br><span class="line">        frame-&gt;pts = ost-&gt;sync_opts;</span><br><span class="line">    ost-&gt;sync_opts = frame-&gt;pts + frame-&gt;nb_samples;</span><br><span class="line">    ost-&gt;samples_encoded += frame-&gt;nb_samples;</span><br><span class="line">    ost-&gt;frames_encoded++;</span><br><span class="line"></span><br><span class="line">    av_assert0(pkt.size || !pkt.data);</span><br><span class="line">    update_benchmark(<span class="literal">NULL</span>);</span><br><span class="line">    <span class="keyword">if</span> (debug_ts) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;encoder &lt;- type:audio &quot;</span></span><br><span class="line">               <span class="string">&quot;frame_pts:%s frame_pts_time:%s time_base:%d/%d\n&quot;</span>,</span><br><span class="line">               av_ts2str(frame-&gt;pts), av_ts2timestr(frame-&gt;pts, &amp;enc-&gt;time_base),</span><br><span class="line">               enc-&gt;time_base.num, enc-&gt;time_base.den);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    ret = avcodec_send_frame(enc, frame);</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">goto</span> error;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span> (<span class="number">1</span>) &#123;</span><br><span class="line">        ret = avcodec_receive_packet(enc, &amp;pkt);</span><br><span class="line">        <span class="keyword">if</span> (ret == AVERROR(EAGAIN))</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">goto</span> error;</span><br><span class="line"></span><br><span class="line">        update_benchmark(<span class="string">&quot;encode_audio %d.%d&quot;</span>, ost-&gt;file_index, ost-&gt;index);</span><br><span class="line"></span><br><span class="line">        av_packet_rescale_ts(&amp;pkt, enc-&gt;time_base, ost-&gt;mux_timebase);  <span class="comment">// 转换时间戳</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (debug_ts) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;encoder -&gt; type:audio &quot;</span></span><br><span class="line">                   <span class="string">&quot;pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n&quot;</span>,</span><br><span class="line">                   av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &amp;enc-&gt;time_base),</span><br><span class="line">                   av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &amp;enc-&gt;time_base));</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        output_packet(of, &amp;pkt, ost, <span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">error:</span><br><span class="line">    av_log(<span class="literal">NULL</span>, AV_LOG_FATAL, <span class="string">&quot;Audio encoding failed\n&quot;</span>);</span><br><span class="line">    exit_program(<span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">do_video_out</span><span class="params">(OutputFile *of,</span></span></span><br><span class="line"><span class="function"><span class="params">                         OutputStream *ost,</span></span></span><br><span class="line"><span class="function"><span class="params">                         AVFrame *next_picture,</span></span></span><br><span class="line"><span class="function"><span class="params">                         <span class="keyword">double</span> sync_ipts)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> ret, format_video_sync;</span><br><span class="line">    AVPacket pkt;</span><br><span class="line">    AVCodecContext *enc = ost-&gt;enc_ctx;</span><br><span class="line">    AVCodecParameters *mux_par = ost-&gt;st-&gt;codecpar;</span><br><span class="line">    AVRational frame_rate;</span><br><span class="line">    <span class="keyword">int</span> nb_frames, nb0_frames, i;</span><br><span class="line">    <span class="keyword">double</span> delta, delta0;</span><br><span class="line">    <span class="keyword">double</span> duration = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> frame_size = <span class="number">0</span>;</span><br><span class="line">    InputStream *ist = <span class="literal">NULL</span>;</span><br><span class="line">    AVFilterContext *filter = ost-&gt;filter-&gt;filter;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ost-&gt;source_index &gt;= <span class="number">0</span>)</span><br><span class="line">        ist = input_streams[ost-&gt;source_index];</span><br><span class="line"></span><br><span class="line">    frame_rate = av_buffersink_get_frame_rate(filter);</span><br><span class="line">    <span class="keyword">if</span> (frame_rate.num &gt; <span class="number">0</span> &amp;&amp; frame_rate.den &gt; <span class="number">0</span>)</span><br><span class="line">        duration = <span class="number">1</span>/(av_q2d(frame_rate) * av_q2d(enc-&gt;time_base));</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(ist &amp;&amp; ist-&gt;st-&gt;start_time != AV_NOPTS_VALUE &amp;&amp; ist-&gt;st-&gt;first_dts != AV_NOPTS_VALUE &amp;&amp; ost-&gt;frame_rate.num)</span><br><span class="line">        duration = FFMIN(duration, <span class="number">1</span>/(av_q2d(ost-&gt;frame_rate) * av_q2d(enc-&gt;time_base)));</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!ost-&gt;filters_script &amp;&amp;</span><br><span class="line">        !ost-&gt;filters &amp;&amp;</span><br><span class="line">        (nb_filtergraphs == <span class="number">0</span> || !filtergraphs[<span class="number">0</span>]-&gt;graph_desc) &amp;&amp;</span><br><span class="line">        next_picture &amp;&amp;</span><br><span class="line">        ist &amp;&amp;</span><br><span class="line">        lrintf(next_picture-&gt;pkt_duration * av_q2d(ist-&gt;st-&gt;time_base) / av_q2d(enc-&gt;time_base)) &gt; <span class="number">0</span>) &#123;</span><br><span class="line">        duration = lrintf(next_picture-&gt;pkt_duration * av_q2d(ist-&gt;st-&gt;time_base) / av_q2d(enc-&gt;time_base));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!next_picture) &#123;</span><br><span class="line">        <span class="comment">//end, flushing</span></span><br><span class="line">        nb0_frames = nb_frames = mid_pred(ost-&gt;last_nb0_frames[<span class="number">0</span>],</span><br><span class="line">                                          ost-&gt;last_nb0_frames[<span class="number">1</span>],</span><br><span class="line">                                          ost-&gt;last_nb0_frames[<span class="number">2</span>]);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        delta0 = sync_ipts - ost-&gt;sync_opts; <span class="comment">// delta0 is the &quot;drift&quot; between the input frame (next_picture) and where it would fall in the output.</span></span><br><span class="line">        delta  = delta0 + duration;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/* by default, we output a single frame */</span></span><br><span class="line">        nb0_frames = <span class="number">0</span>; <span class="comment">// tracks the number of times the PREVIOUS frame should be duplicated, mostly for variable framerate (VFR)</span></span><br><span class="line">        nb_frames = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">        format_video_sync = video_sync_method;</span><br><span class="line">        <span class="keyword">if</span> (format_video_sync == VSYNC_AUTO) &#123;</span><br><span class="line">            <span class="keyword">if</span>(!<span class="built_in">strcmp</span>(of-&gt;ctx-&gt;oformat-&gt;name, <span class="string">&quot;avi&quot;</span>)) &#123;</span><br><span class="line">                format_video_sync = VSYNC_VFR;</span><br><span class="line">            &#125; <span class="keyword">else</span></span><br><span class="line">                format_video_sync = (of-&gt;ctx-&gt;oformat-&gt;flags &amp; AVFMT_VARIABLE_FPS) ? ((of-&gt;ctx-&gt;oformat-&gt;flags &amp; AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : VSYNC_VFR) : VSYNC_CFR;</span><br><span class="line">            <span class="keyword">if</span> (   ist</span><br><span class="line">                &amp;&amp; format_video_sync == VSYNC_CFR</span><br><span class="line">                &amp;&amp; input_files[ist-&gt;file_index]-&gt;ctx-&gt;nb_streams == <span class="number">1</span></span><br><span class="line">                &amp;&amp; input_files[ist-&gt;file_index]-&gt;input_ts_offset == <span class="number">0</span>) &#123;</span><br><span class="line">                format_video_sync = VSYNC_VSCFR;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (format_video_sync == VSYNC_CFR &amp;&amp; copy_ts) &#123;</span><br><span class="line">                format_video_sync = VSYNC_VSCFR;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        ost-&gt;is_cfr = (format_video_sync == VSYNC_CFR || format_video_sync == VSYNC_VSCFR);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (delta0 &lt; <span class="number">0</span> &amp;&amp;</span><br><span class="line">            delta &gt; <span class="number">0</span> &amp;&amp;</span><br><span class="line">            format_video_sync != VSYNC_PASSTHROUGH &amp;&amp;</span><br><span class="line">            format_video_sync != VSYNC_DROP) &#123;</span><br><span class="line">            <span class="keyword">if</span> (delta0 &lt; <span class="number">-0.6</span>) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;Past duration %f too large\n&quot;</span>, -delta0);</span><br><span class="line">            &#125; <span class="keyword">else</span></span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_DEBUG, <span class="string">&quot;Clipping frame in rate conversion by %f\n&quot;</span>, -delta0);</span><br><span class="line">            sync_ipts = ost-&gt;sync_opts;</span><br><span class="line">            duration += delta0;</span><br><span class="line">            delta0 = <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">switch</span> (format_video_sync) &#123;</span><br><span class="line">        <span class="keyword">case</span> VSYNC_VSCFR:</span><br><span class="line">            <span class="keyword">if</span> (ost-&gt;frame_number == <span class="number">0</span> &amp;&amp; delta0 &gt;= <span class="number">0.5</span>) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_DEBUG, <span class="string">&quot;Not duplicating %d initial frames\n&quot;</span>, (<span class="keyword">int</span>)lrintf(delta0));</span><br><span class="line">                delta = duration;</span><br><span class="line">                delta0 = <span class="number">0</span>;</span><br><span class="line">                ost-&gt;sync_opts = lrint(sync_ipts);</span><br><span class="line">            &#125;</span><br><span class="line">        <span class="keyword">case</span> VSYNC_CFR:</span><br><span class="line">            <span class="comment">// FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c</span></span><br><span class="line">            <span class="keyword">if</span> (frame_drop_threshold &amp;&amp; delta &lt; frame_drop_threshold &amp;&amp; ost-&gt;frame_number) &#123;</span><br><span class="line">                nb_frames = <span class="number">0</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (delta &lt; <span class="number">-1.1</span>)</span><br><span class="line">                nb_frames = <span class="number">0</span>;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span> (delta &gt; <span class="number">1.1</span>) &#123;</span><br><span class="line">                nb_frames = lrintf(delta);</span><br><span class="line">                <span class="keyword">if</span> (delta0 &gt; <span class="number">1.1</span>)</span><br><span class="line">                    nb0_frames = lrintf(delta0 - <span class="number">0.6</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> VSYNC_VFR:</span><br><span class="line">            <span class="keyword">if</span> (delta &lt;= <span class="number">-0.6</span>)</span><br><span class="line">                nb_frames = <span class="number">0</span>;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span> (delta &gt; <span class="number">0.6</span>)</span><br><span class="line">                ost-&gt;sync_opts = lrint(sync_ipts);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> VSYNC_DROP:</span><br><span class="line">        <span class="keyword">case</span> VSYNC_PASSTHROUGH:</span><br><span class="line">            ost-&gt;sync_opts = lrint(sync_ipts);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">default</span>:</span><br><span class="line">            av_assert0(<span class="number">0</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    nb_frames = FFMIN(nb_frames, ost-&gt;max_frames - ost-&gt;frame_number);</span><br><span class="line">    nb0_frames = FFMIN(nb0_frames, nb_frames);</span><br><span class="line"></span><br><span class="line">    memmove(ost-&gt;last_nb0_frames + <span class="number">1</span>,</span><br><span class="line">            ost-&gt;last_nb0_frames,</span><br><span class="line">            <span class="keyword">sizeof</span>(ost-&gt;last_nb0_frames[<span class="number">0</span>]) * (FF_ARRAY_ELEMS(ost-&gt;last_nb0_frames) - <span class="number">1</span>));</span><br><span class="line">    ost-&gt;last_nb0_frames[<span class="number">0</span>] = nb0_frames;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (nb0_frames == <span class="number">0</span> &amp;&amp; ost-&gt;last_dropped) &#123;</span><br><span class="line">        nb_frames_drop++;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE,</span><br><span class="line">               <span class="string">&quot;*** dropping frame %d from stream %d at ts %&quot;</span>PRId64<span class="string">&quot;\n&quot;</span>,</span><br><span class="line">               ost-&gt;frame_number, ost-&gt;st-&gt;index, ost-&gt;last_frame-&gt;pts);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (nb_frames &gt; (nb0_frames &amp;&amp; ost-&gt;last_dropped) + (nb_frames &gt; nb0_frames)) &#123;</span><br><span class="line">        <span class="keyword">if</span> (nb_frames &gt; dts_error_threshold * <span class="number">30</span>) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;%d frame duplication too large, skipping\n&quot;</span>, nb_frames - <span class="number">1</span>);</span><br><span class="line">            nb_frames_drop++;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        nb_frames_dup += nb_frames - (nb0_frames &amp;&amp; ost-&gt;last_dropped) - (nb_frames &gt; nb0_frames);</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;*** %d dup!\n&quot;</span>, nb_frames - <span class="number">1</span>);</span><br><span class="line">        <span class="keyword">if</span> (nb_frames_dup &gt; dup_warning) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_WARNING, <span class="string">&quot;More than %d frames duplicated\n&quot;</span>, dup_warning);</span><br><span class="line">            dup_warning *= <span class="number">10</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    ost-&gt;last_dropped = nb_frames == nb0_frames &amp;&amp; next_picture;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* duplicates frame if needed */</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_frames; i++) &#123;</span><br><span class="line">        AVFrame *in_picture;</span><br><span class="line">        <span class="keyword">int</span> forced_keyframe = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">double</span> pts_time;</span><br><span class="line">        av_init_packet(&amp;pkt);</span><br><span class="line">        pkt.data = <span class="literal">NULL</span>;</span><br><span class="line">        pkt.size = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (i &lt; nb0_frames &amp;&amp; ost-&gt;last_frame) &#123;</span><br><span class="line">            in_picture = ost-&gt;last_frame;</span><br><span class="line">        &#125; <span class="keyword">else</span></span><br><span class="line">            in_picture = next_picture;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!in_picture)</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">        in_picture-&gt;pts = ost-&gt;sync_opts;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!check_recording_time(ost))</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (enc-&gt;flags &amp; (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME) &amp;&amp;</span><br><span class="line">            ost-&gt;top_field_first &gt;= <span class="number">0</span>)</span><br><span class="line">            in_picture-&gt;top_field_first = !!ost-&gt;top_field_first;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (in_picture-&gt;interlaced_frame) &#123;</span><br><span class="line">            <span class="keyword">if</span> (enc-&gt;codec-&gt;id == AV_CODEC_ID_MJPEG)</span><br><span class="line">                mux_par-&gt;field_order = in_picture-&gt;top_field_first ? AV_FIELD_TT:AV_FIELD_BB;</span><br><span class="line">            <span class="keyword">else</span></span><br><span class="line">                mux_par-&gt;field_order = in_picture-&gt;top_field_first ? AV_FIELD_TB:AV_FIELD_BT;</span><br><span class="line">        &#125; <span class="keyword">else</span></span><br><span class="line">            mux_par-&gt;field_order = AV_FIELD_PROGRESSIVE;</span><br><span class="line"></span><br><span class="line">        in_picture-&gt;quality = enc-&gt;global_quality;</span><br><span class="line">        in_picture-&gt;pict_type = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;forced_kf_ref_pts == AV_NOPTS_VALUE &amp;&amp;</span><br><span class="line">            in_picture-&gt;pts != AV_NOPTS_VALUE)</span><br><span class="line">            ost-&gt;forced_kf_ref_pts = in_picture-&gt;pts;</span><br><span class="line"></span><br><span class="line">        pts_time = in_picture-&gt;pts != AV_NOPTS_VALUE ?</span><br><span class="line">            (in_picture-&gt;pts - ost-&gt;forced_kf_ref_pts) * av_q2d(enc-&gt;time_base) : NAN;</span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;forced_kf_index &lt; ost-&gt;forced_kf_count &amp;&amp;</span><br><span class="line">            in_picture-&gt;pts &gt;= ost-&gt;forced_kf_pts[ost-&gt;forced_kf_index]) &#123;</span><br><span class="line">            ost-&gt;forced_kf_index++;</span><br><span class="line">            forced_keyframe = <span class="number">1</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (ost-&gt;forced_keyframes_pexpr) &#123;</span><br><span class="line">            <span class="keyword">double</span> res;</span><br><span class="line">            ost-&gt;forced_keyframes_expr_const_values[FKF_T] = pts_time;</span><br><span class="line">            res = av_expr_eval(ost-&gt;forced_keyframes_pexpr,</span><br><span class="line">                               ost-&gt;forced_keyframes_expr_const_values, <span class="literal">NULL</span>);</span><br><span class="line">            ff_dlog(<span class="literal">NULL</span>, <span class="string">&quot;force_key_frame: n:%f n_forced:%f prev_forced_n:%f t:%f prev_forced_t:%f -&gt; res:%f\n&quot;</span>,</span><br><span class="line">                    ost-&gt;forced_keyframes_expr_const_values[FKF_N],</span><br><span class="line">                    ost-&gt;forced_keyframes_expr_const_values[FKF_N_FORCED],</span><br><span class="line">                    ost-&gt;forced_keyframes_expr_const_values[FKF_PREV_FORCED_N],</span><br><span class="line">                    ost-&gt;forced_keyframes_expr_const_values[FKF_T],</span><br><span class="line">                    ost-&gt;forced_keyframes_expr_const_values[FKF_PREV_FORCED_T],</span><br><span class="line">                    res);</span><br><span class="line">            <span class="keyword">if</span> (res) &#123;</span><br><span class="line">                forced_keyframe = <span class="number">1</span>;</span><br><span class="line">                ost-&gt;forced_keyframes_expr_const_values[FKF_PREV_FORCED_N] =</span><br><span class="line">                    ost-&gt;forced_keyframes_expr_const_values[FKF_N];</span><br><span class="line">                ost-&gt;forced_keyframes_expr_const_values[FKF_PREV_FORCED_T] =</span><br><span class="line">                    ost-&gt;forced_keyframes_expr_const_values[FKF_T];</span><br><span class="line">                ost-&gt;forced_keyframes_expr_const_values[FKF_N_FORCED] += <span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            ost-&gt;forced_keyframes_expr_const_values[FKF_N] += <span class="number">1</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (   ost-&gt;forced_keyframes</span><br><span class="line">                   &amp;&amp; !<span class="built_in">strncmp</span>(ost-&gt;forced_keyframes, <span class="string">&quot;source&quot;</span>, <span class="number">6</span>)</span><br><span class="line">                   &amp;&amp; in_picture-&gt;key_frame==<span class="number">1</span>) &#123;</span><br><span class="line">            forced_keyframe = <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (forced_keyframe) &#123;</span><br><span class="line">            in_picture-&gt;pict_type = AV_PICTURE_TYPE_I;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_DEBUG, <span class="string">&quot;Forced keyframe at time %f\n&quot;</span>, pts_time);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        update_benchmark(<span class="literal">NULL</span>);</span><br><span class="line">        <span class="keyword">if</span> (debug_ts) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;encoder &lt;- type:video &quot;</span></span><br><span class="line">                   <span class="string">&quot;frame_pts:%s frame_pts_time:%s time_base:%d/%d\n&quot;</span>,</span><br><span class="line">                   av_ts2str(in_picture-&gt;pts), av_ts2timestr(in_picture-&gt;pts, &amp;enc-&gt;time_base),</span><br><span class="line">                   enc-&gt;time_base.num, enc-&gt;time_base.den);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        ost-&gt;frames_encoded++;</span><br><span class="line"></span><br><span class="line">        ret = avcodec_send_frame(enc, in_picture);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">goto</span> error;</span><br><span class="line">        <span class="comment">// Make sure Closed Captions will not be duplicated</span></span><br><span class="line">        av_frame_remove_side_data(in_picture, AV_FRAME_DATA_A53_CC);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span> (<span class="number">1</span>) &#123;</span><br><span class="line">            ret = avcodec_receive_packet(enc, &amp;pkt);</span><br><span class="line">            update_benchmark(<span class="string">&quot;encode_video %d.%d&quot;</span>, ost-&gt;file_index, ost-&gt;index);</span><br><span class="line">            <span class="keyword">if</span> (ret == AVERROR(EAGAIN))</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">                <span class="keyword">goto</span> error;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (debug_ts) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;encoder -&gt; type:video &quot;</span></span><br><span class="line">                       <span class="string">&quot;pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n&quot;</span>,</span><br><span class="line">                       av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &amp;enc-&gt;time_base),</span><br><span class="line">                       av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &amp;enc-&gt;time_base));</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (pkt.pts == AV_NOPTS_VALUE &amp;&amp; !(enc-&gt;codec-&gt;capabilities &amp; AV_CODEC_CAP_DELAY))</span><br><span class="line">                pkt.pts = ost-&gt;sync_opts;</span><br><span class="line"></span><br><span class="line">            av_packet_rescale_ts(&amp;pkt, enc-&gt;time_base, ost-&gt;mux_timebase);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (debug_ts) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;encoder -&gt; type:video &quot;</span></span><br><span class="line">                    <span class="string">&quot;pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n&quot;</span>,</span><br><span class="line">                    av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &amp;ost-&gt;mux_timebase),</span><br><span class="line">                    av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &amp;ost-&gt;mux_timebase));</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            frame_size = pkt.size;</span><br><span class="line">            output_packet(of, &amp;pkt, ost, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">            <span class="comment">/* if two pass, output log */</span></span><br><span class="line">            <span class="keyword">if</span> (ost-&gt;logfile &amp;&amp; enc-&gt;stats_out) &#123;</span><br><span class="line">                <span class="built_in">fprintf</span>(ost-&gt;logfile, <span class="string">&quot;%s&quot;</span>, enc-&gt;stats_out);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        ost-&gt;sync_opts++;</span><br><span class="line">        <span class="comment">/*</span></span><br><span class="line"><span class="comment">         * For video, number of frames in == number of packets out.</span></span><br><span class="line"><span class="comment">         * But there may be reordering, so we can&#x27;t throw away frames on encoder</span></span><br><span class="line"><span class="comment">         * flush, we need to limit them here, before they go into encoder.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        ost-&gt;frame_number++;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (vstats_filename &amp;&amp; frame_size)</span><br><span class="line">            do_video_stats(ost, frame_size);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!ost-&gt;last_frame)</span><br><span class="line">        ost-&gt;last_frame = av_frame_alloc();</span><br><span class="line">    av_frame_unref(ost-&gt;last_frame);</span><br><span class="line">    <span class="keyword">if</span> (next_picture &amp;&amp; ost-&gt;last_frame)</span><br><span class="line">        av_frame_ref(ost-&gt;last_frame, next_picture);</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">        av_frame_free(&amp;ost-&gt;last_frame);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">error:</span><br><span class="line">    av_log(<span class="literal">NULL</span>, AV_LOG_FATAL, <span class="string">&quot;Video encoding failed\n&quot;</span>);</span><br><span class="line">    exit_program(<span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">double</span> <span class="title">psnr</span><span class="params">(<span class="keyword">double</span> d)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">-10.0</span> * <span class="built_in">log10</span>(d);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">do_video_stats</span><span class="params">(OutputStream *ost, <span class="keyword">int</span> frame_size)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    AVCodecContext *enc;</span><br><span class="line">    <span class="keyword">int</span> frame_number;</span><br><span class="line">    <span class="keyword">double</span> ti1, bitrate, avg_bitrate;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* this is executed just the first time do_video_stats is called */</span></span><br><span class="line">    <span class="keyword">if</span> (!vstats_file) &#123;</span><br><span class="line">        vstats_file = fopen(vstats_filename, <span class="string">&quot;w&quot;</span>);</span><br><span class="line">        <span class="keyword">if</span> (!vstats_file) &#123;</span><br><span class="line">            perror(<span class="string">&quot;fopen&quot;</span>);</span><br><span class="line">            exit_program(<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    enc = ost-&gt;enc_ctx;</span><br><span class="line">    <span class="keyword">if</span> (enc-&gt;codec_type == AVMEDIA_TYPE_VIDEO) &#123;</span><br><span class="line">        frame_number = ost-&gt;st-&gt;nb_frames;</span><br><span class="line">        <span class="keyword">if</span> (vstats_version &lt;= <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="built_in">fprintf</span>(vstats_file, <span class="string">&quot;frame= %5d q= %2.1f &quot;</span>, frame_number,</span><br><span class="line">                    ost-&gt;quality / (<span class="keyword">float</span>)FF_QP2LAMBDA);</span><br><span class="line">        &#125; <span class="keyword">else</span>  &#123;</span><br><span class="line">            <span class="built_in">fprintf</span>(vstats_file, <span class="string">&quot;out= %2d st= %2d frame= %5d q= %2.1f &quot;</span>, ost-&gt;file_index, ost-&gt;index, frame_number,</span><br><span class="line">                    ost-&gt;quality / (<span class="keyword">float</span>)FF_QP2LAMBDA);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;error[<span class="number">0</span>]&gt;=<span class="number">0</span> &amp;&amp; (enc-&gt;flags &amp; AV_CODEC_FLAG_PSNR))</span><br><span class="line">            <span class="built_in">fprintf</span>(vstats_file, <span class="string">&quot;PSNR= %6.2f &quot;</span>, psnr(ost-&gt;error[<span class="number">0</span>] / (enc-&gt;width * enc-&gt;height * <span class="number">255.0</span> * <span class="number">255.0</span>)));</span><br><span class="line"></span><br><span class="line">        <span class="built_in">fprintf</span>(vstats_file,<span class="string">&quot;f_size= %6d &quot;</span>, frame_size);</span><br><span class="line">        <span class="comment">/* compute pts value */</span></span><br><span class="line">        ti1 = av_stream_get_end_pts(ost-&gt;st) * av_q2d(ost-&gt;st-&gt;time_base);</span><br><span class="line">        <span class="keyword">if</span> (ti1 &lt; <span class="number">0.01</span>)</span><br><span class="line">            ti1 = <span class="number">0.01</span>;</span><br><span class="line"></span><br><span class="line">        bitrate     = (frame_size * <span class="number">8</span>) / av_q2d(enc-&gt;time_base) / <span class="number">1000.0</span>;</span><br><span class="line">        avg_bitrate = (<span class="keyword">double</span>)(ost-&gt;data_size * <span class="number">8</span>) / ti1 / <span class="number">1000.0</span>;</span><br><span class="line">        <span class="built_in">fprintf</span>(vstats_file, <span class="string">&quot;s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s &quot;</span>,</span><br><span class="line">               (<span class="keyword">double</span>)ost-&gt;data_size / <span class="number">1024</span>, ti1, bitrate, avg_bitrate);</span><br><span class="line">        <span class="built_in">fprintf</span>(vstats_file, <span class="string">&quot;type= %c\n&quot;</span>, av_get_picture_type_char(ost-&gt;pict_type));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">init_output_stream</span><span class="params">(OutputStream *ost, <span class="keyword">char</span> *error, <span class="keyword">int</span> error_len)</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">finish_output_stream</span><span class="params">(OutputStream *ost)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    OutputFile *of = output_files[ost-&gt;file_index];</span><br><span class="line">    <span class="keyword">int</span> i;</span><br><span class="line"></span><br><span class="line">    ost-&gt;finished = ENCODER_FINISHED | MUXER_FINISHED;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (of-&gt;shortest) &#123;</span><br><span class="line">        <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; of-&gt;ctx-&gt;nb_streams; i++)</span><br><span class="line">            output_streams[of-&gt;ost_index + i]-&gt;finished = ENCODER_FINISHED | MUXER_FINISHED;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Get and encode new output from any of the filtergraphs, without causing</span></span><br><span class="line"><span class="comment"> * activity.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * @return  0 for success, &lt;0 for severe errors</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">reap_filters</span><span class="params">(<span class="keyword">int</span> flush)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    AVFrame *filtered_frame = <span class="literal">NULL</span>;</span><br><span class="line">    <span class="keyword">int</span> i;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* Reap all buffers present in the buffer sinks */</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_streams; i++) &#123;</span><br><span class="line">        OutputStream *ost = output_streams[i];</span><br><span class="line">        OutputFile    *of = output_files[ost-&gt;file_index];</span><br><span class="line">        AVFilterContext *filter;</span><br><span class="line">        AVCodecContext *enc = ost-&gt;enc_ctx;</span><br><span class="line">        <span class="keyword">int</span> ret = <span class="number">0</span>;</span><br><span class="line">        <span class="comment">//对应的stream copy的时候没有filter</span></span><br><span class="line">        <span class="keyword">if</span> (!ost-&gt;filter || !ost-&gt;filter-&gt;graph-&gt;graph)</span><br><span class="line">            <span class="keyword">continue</span>;   <span class="comment">// 还没有创建graph</span></span><br><span class="line">        filter = ost-&gt;filter-&gt;filter;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!ost-&gt;initialized) &#123;    <span class="comment">// 只初始化一次</span></span><br><span class="line">            <span class="keyword">char</span> error[<span class="number">1024</span>] = <span class="string">&quot;&quot;</span>;</span><br><span class="line">            ret = init_output_stream(ost, error, <span class="keyword">sizeof</span>(error));</span><br><span class="line">            <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;Error initializing output stream %d:%d -- %s\n&quot;</span>,</span><br><span class="line">                       ost-&gt;file_index, ost-&gt;index, error);</span><br><span class="line">                exit_program(<span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!ost-&gt;filtered_frame &amp;&amp; !(ost-&gt;filtered_frame = av_frame_alloc())) &#123;</span><br><span class="line">            <span class="keyword">return</span> AVERROR(ENOMEM);</span><br><span class="line">        &#125;</span><br><span class="line">        filtered_frame = ost-&gt;filtered_frame;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span> (<span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">double</span> float_pts = AV_NOPTS_VALUE; <span class="comment">// this is identical to filtered_frame.pts but with higher precision</span></span><br><span class="line">            ret = av_buffersink_get_frame_flags(filter, filtered_frame, <span class="comment">// 从graph输出口获取filter数据</span></span><br><span class="line">                                               AV_BUFFERSINK_FLAG_NO_REQUEST);</span><br><span class="line">            <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="keyword">if</span> (ret != AVERROR(EAGAIN) &amp;&amp; ret != AVERROR_EOF) &#123;</span><br><span class="line">                    av_log(<span class="literal">NULL</span>, AV_LOG_WARNING,</span><br><span class="line">                           <span class="string">&quot;Error in av_buffersink_get_frame_flags(): %s\n&quot;</span>, av_err2str(ret));</span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (flush &amp;&amp; ret == AVERROR_EOF) &#123;</span><br><span class="line">                    <span class="keyword">if</span> (av_buffersink_get_type(filter) == AVMEDIA_TYPE_VIDEO)</span><br><span class="line">                        do_video_out(of, ost, <span class="literal">NULL</span>, AV_NOPTS_VALUE);</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (ost-&gt;finished) &#123;</span><br><span class="line">                av_frame_unref(filtered_frame);</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (filtered_frame-&gt;pts != AV_NOPTS_VALUE) &#123;</span><br><span class="line">                <span class="keyword">int64_t</span> start_time = (of-&gt;start_time == AV_NOPTS_VALUE) ? <span class="number">0</span> : of-&gt;start_time;</span><br><span class="line">                AVRational filter_tb = av_buffersink_get_time_base(filter); <span class="comment">// filter out的time_base</span></span><br><span class="line">                AVRational tb = enc-&gt;time_base;     <span class="comment">// 编码器的time_base</span></span><br><span class="line">                <span class="keyword">int</span> extra_bits = av_clip(<span class="number">29</span> - av_log2(tb.den), <span class="number">0</span>, <span class="number">16</span>);</span><br><span class="line"></span><br><span class="line">                tb.den &lt;&lt;= extra_bits;</span><br><span class="line">                float_pts =</span><br><span class="line">                    av_rescale_q(filtered_frame-&gt;pts, filter_tb, tb) -</span><br><span class="line">                    av_rescale_q(start_time, AV_TIME_BASE_Q, tb);   <span class="comment">// 转成统一的timebase对比</span></span><br><span class="line">                float_pts /= <span class="number">1</span> &lt;&lt; extra_bits;</span><br><span class="line">                <span class="comment">// avoid exact midoints to reduce the chance of rounding differences, this can be removed in case the fps code is changed to work with integers</span></span><br><span class="line">                float_pts += FFSIGN(float_pts) * <span class="number">1.0</span> / (<span class="number">1</span>&lt;&lt;<span class="number">17</span>);</span><br><span class="line"></span><br><span class="line">                filtered_frame-&gt;pts =</span><br><span class="line">                    av_rescale_q(filtered_frame-&gt;pts, filter_tb, enc-&gt;time_base) -</span><br><span class="line">                    av_rescale_q(start_time, AV_TIME_BASE_Q, enc-&gt;time_base);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">switch</span> (av_buffersink_get_type(filter)) &#123;</span><br><span class="line">            <span class="keyword">case</span> AVMEDIA_TYPE_VIDEO:</span><br><span class="line">                <span class="keyword">if</span> (!ost-&gt;frame_aspect_ratio.num)</span><br><span class="line">                    enc-&gt;sample_aspect_ratio = filtered_frame-&gt;sample_aspect_ratio;</span><br><span class="line"></span><br><span class="line">                <span class="keyword">if</span> (debug_ts) &#123;</span><br><span class="line">                    av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;filter -&gt; pts:%s pts_time:%s exact:%f time_base:%d/%d\n&quot;</span>,</span><br><span class="line">                            av_ts2str(filtered_frame-&gt;pts), av_ts2timestr(filtered_frame-&gt;pts, &amp;enc-&gt;time_base),</span><br><span class="line">                            float_pts,</span><br><span class="line">                            enc-&gt;time_base.num, enc-&gt;time_base.den);</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                do_video_out(of, ost, filtered_frame, float_pts);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> AVMEDIA_TYPE_AUDIO:</span><br><span class="line">                <span class="keyword">if</span> (!(enc-&gt;codec-&gt;capabilities &amp; AV_CODEC_CAP_PARAM_CHANGE) &amp;&amp;</span><br><span class="line">                    enc-&gt;channels != filtered_frame-&gt;channels) &#123;</span><br><span class="line">                    av_log(<span class="literal">NULL</span>, AV_LOG_ERROR,</span><br><span class="line">                           <span class="string">&quot;Audio filter graph output is not normalized and encoder does not support parameter changes\n&quot;</span>);</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                do_audio_out(of, ost, filtered_frame);  <span class="comment">// 音频</span></span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">default</span>:</span><br><span class="line">                <span class="comment">// TODO support subtitle filters</span></span><br><span class="line">                av_assert0(<span class="number">0</span>);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            av_frame_unref(filtered_frame);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">print_final_stats</span><span class="params">(<span class="keyword">int64_t</span> total_size)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">uint64_t</span> video_size = <span class="number">0</span>, audio_size = <span class="number">0</span>, extra_size = <span class="number">0</span>, other_size = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">uint64_t</span> subtitle_size = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">uint64_t</span> data_size = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">float</span> percent = <span class="number">-1.0</span>;</span><br><span class="line">    <span class="keyword">int</span> i, j;</span><br><span class="line">    <span class="keyword">int</span> pass1_used = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_streams; i++) &#123;</span><br><span class="line">        OutputStream *ost = output_streams[i];</span><br><span class="line">        <span class="keyword">switch</span> (ost-&gt;enc_ctx-&gt;codec_type) &#123;</span><br><span class="line">            <span class="keyword">case</span> AVMEDIA_TYPE_VIDEO: video_size += ost-&gt;data_size; <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> AVMEDIA_TYPE_AUDIO: audio_size += ost-&gt;data_size; <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> AVMEDIA_TYPE_SUBTITLE: subtitle_size += ost-&gt;data_size; <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">default</span>:                 other_size += ost-&gt;data_size; <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        extra_size += ost-&gt;enc_ctx-&gt;extradata_size;</span><br><span class="line">        data_size  += ost-&gt;data_size;</span><br><span class="line">        <span class="keyword">if</span> (   (ost-&gt;enc_ctx-&gt;flags &amp; (AV_CODEC_FLAG_PASS1 | AV_CODEC_FLAG_PASS2))</span><br><span class="line">            != AV_CODEC_FLAG_PASS1)</span><br><span class="line">            pass1_used = <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (data_size &amp;&amp; total_size&gt;<span class="number">0</span> &amp;&amp; total_size &gt;= data_size)</span><br><span class="line">        percent = <span class="number">100.0</span> * (total_size - data_size) / data_size;</span><br><span class="line"></span><br><span class="line">    av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;video:%1.0fkB audio:%1.0fkB subtitle:%1.0fkB other streams:%1.0fkB global headers:%1.0fkB muxing overhead: &quot;</span>,</span><br><span class="line">           video_size / <span class="number">1024.0</span>,</span><br><span class="line">           audio_size / <span class="number">1024.0</span>,</span><br><span class="line">           subtitle_size / <span class="number">1024.0</span>,</span><br><span class="line">           other_size / <span class="number">1024.0</span>,</span><br><span class="line">           extra_size / <span class="number">1024.0</span>);</span><br><span class="line">    <span class="keyword">if</span> (percent &gt;= <span class="number">0.0</span>)</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;%f%%&quot;</span>, percent);</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;unknown&quot;</span>);</span><br><span class="line">    av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;\n&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* print verbose per-stream stats */</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_input_files; i++) &#123;</span><br><span class="line">        InputFile *f = input_files[i];</span><br><span class="line">        <span class="keyword">uint64_t</span> total_packets = <span class="number">0</span>, total_size = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;Input file #%d (%s):\n&quot;</span>,</span><br><span class="line">               i, f-&gt;ctx-&gt;url);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; f-&gt;nb_streams; j++) &#123;</span><br><span class="line">            InputStream *ist = input_streams[f-&gt;ist_index + j];</span><br><span class="line">            <span class="class"><span class="keyword">enum</span> <span class="title">AVMediaType</span> <span class="title">type</span> =</span> ist-&gt;dec_ctx-&gt;codec_type;</span><br><span class="line"></span><br><span class="line">            total_size    += ist-&gt;data_size;</span><br><span class="line">            total_packets += ist-&gt;nb_packets;</span><br><span class="line"></span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;  Input stream #%d:%d (%s): &quot;</span>,</span><br><span class="line">                   i, j, media_type_string(type));</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;%&quot;</span>PRIu64<span class="string">&quot; packets read (%&quot;</span>PRIu64<span class="string">&quot; bytes); &quot;</span>,</span><br><span class="line">                   ist-&gt;nb_packets, ist-&gt;data_size);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (ist-&gt;decoding_needed) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;%&quot;</span>PRIu64<span class="string">&quot; frames decoded&quot;</span>,</span><br><span class="line">                       ist-&gt;frames_decoded);</span><br><span class="line">                <span class="keyword">if</span> (type == AVMEDIA_TYPE_AUDIO)</span><br><span class="line">                    av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot; (%&quot;</span>PRIu64<span class="string">&quot; samples)&quot;</span>, ist-&gt;samples_decoded);</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;; &quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;\n&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;  Total: %&quot;</span>PRIu64<span class="string">&quot; packets (%&quot;</span>PRIu64<span class="string">&quot; bytes) demuxed\n&quot;</span>,</span><br><span class="line">               total_packets, total_size);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_files; i++) &#123;</span><br><span class="line">        OutputFile *of = output_files[i];</span><br><span class="line">        <span class="keyword">uint64_t</span> total_packets = <span class="number">0</span>, total_size = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;Output file #%d (%s):\n&quot;</span>,</span><br><span class="line">               i, of-&gt;ctx-&gt;url);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; of-&gt;ctx-&gt;nb_streams; j++) &#123;</span><br><span class="line">            OutputStream *ost = output_streams[of-&gt;ost_index + j];</span><br><span class="line">            <span class="class"><span class="keyword">enum</span> <span class="title">AVMediaType</span> <span class="title">type</span> =</span> ost-&gt;enc_ctx-&gt;codec_type;</span><br><span class="line"></span><br><span class="line">            total_size    += ost-&gt;data_size;</span><br><span class="line">            total_packets += ost-&gt;packets_written;</span><br><span class="line"></span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;  Output stream #%d:%d (%s): &quot;</span>,</span><br><span class="line">                   i, j, media_type_string(type));</span><br><span class="line">            <span class="keyword">if</span> (ost-&gt;encoding_needed) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;%&quot;</span>PRIu64<span class="string">&quot; frames encoded&quot;</span>,</span><br><span class="line">                       ost-&gt;frames_encoded);</span><br><span class="line">                <span class="keyword">if</span> (type == AVMEDIA_TYPE_AUDIO)</span><br><span class="line">                    av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot; (%&quot;</span>PRIu64<span class="string">&quot; samples)&quot;</span>, ost-&gt;samples_encoded);</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;; &quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;%&quot;</span>PRIu64<span class="string">&quot; packets muxed (%&quot;</span>PRIu64<span class="string">&quot; bytes); &quot;</span>,</span><br><span class="line">                   ost-&gt;packets_written, ost-&gt;data_size);</span><br><span class="line"></span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;\n&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;  Total: %&quot;</span>PRIu64<span class="string">&quot; packets (%&quot;</span>PRIu64<span class="string">&quot; bytes) muxed\n&quot;</span>,</span><br><span class="line">               total_packets, total_size);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(video_size + data_size + audio_size + subtitle_size + extra_size == <span class="number">0</span>)&#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_WARNING, <span class="string">&quot;Output file is empty, nothing was encoded &quot;</span>);</span><br><span class="line">        <span class="keyword">if</span> (pass1_used) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_WARNING, <span class="string">&quot;\n&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_WARNING, <span class="string">&quot;(check -ss / -t / -frames parameters if used)\n&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">print_report</span><span class="params">(<span class="keyword">int</span> is_last_report, <span class="keyword">int64_t</span> timer_start, <span class="keyword">int64_t</span> cur_time)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    AVBPrint buf, buf_script;</span><br><span class="line">    OutputStream *ost;</span><br><span class="line">    AVFormatContext *oc;</span><br><span class="line">    <span class="keyword">int64_t</span> total_size;</span><br><span class="line">    AVCodecContext *enc;</span><br><span class="line">    <span class="keyword">int</span> frame_number, vid, i;</span><br><span class="line">    <span class="keyword">double</span> bitrate;</span><br><span class="line">    <span class="keyword">double</span> speed;</span><br><span class="line">    <span class="keyword">int64_t</span> pts = INT64_MIN + <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int64_t</span> last_time = <span class="number">-1</span>;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> qp_histogram[<span class="number">52</span>];</span><br><span class="line">    <span class="keyword">int</span> hours, mins, secs, us;</span><br><span class="line">    <span class="keyword">const</span> <span class="keyword">char</span> *hours_sign;</span><br><span class="line">    <span class="keyword">int</span> ret;</span><br><span class="line">    <span class="keyword">float</span> t;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!print_stats &amp;&amp; !is_last_report &amp;&amp; !progress_avio)</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!is_last_report) &#123;</span><br><span class="line">        <span class="keyword">if</span> (last_time == <span class="number">-1</span>) &#123;</span><br><span class="line">            last_time = cur_time;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> ((cur_time - last_time) &lt; <span class="number">500000</span>)</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        last_time = cur_time;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    t = (cur_time-timer_start) / <span class="number">1000000.0</span>;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    oc = output_files[<span class="number">0</span>]-&gt;ctx;</span><br><span class="line"></span><br><span class="line">    total_size = avio_size(oc-&gt;pb);</span><br><span class="line">    <span class="keyword">if</span> (total_size &lt;= <span class="number">0</span>) <span class="comment">// FIXME improve avio_size() so it works with non seekable output too</span></span><br><span class="line">        total_size = avio_tell(oc-&gt;pb);</span><br><span class="line"></span><br><span class="line">    vid = <span class="number">0</span>;</span><br><span class="line">    av_bprint_init(&amp;buf, <span class="number">0</span>, AV_BPRINT_SIZE_AUTOMATIC);</span><br><span class="line">    av_bprint_init(&amp;buf_script, <span class="number">0</span>, AV_BPRINT_SIZE_AUTOMATIC);</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_streams; i++) &#123;</span><br><span class="line">        <span class="keyword">float</span> q = <span class="number">-1</span>;</span><br><span class="line">        ost = output_streams[i];</span><br><span class="line">        enc = ost-&gt;enc_ctx;</span><br><span class="line">        <span class="keyword">if</span> (!ost-&gt;stream_copy)</span><br><span class="line">            q = ost-&gt;quality / (<span class="keyword">float</span>) FF_QP2LAMBDA;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (vid &amp;&amp; enc-&gt;codec_type == AVMEDIA_TYPE_VIDEO) &#123;</span><br><span class="line">            av_bprintf(&amp;buf, <span class="string">&quot;q=%2.1f &quot;</span>, q);</span><br><span class="line">            av_bprintf(&amp;buf_script, <span class="string">&quot;stream_%d_%d_q=%.1f\n&quot;</span>,</span><br><span class="line">                       ost-&gt;file_index, ost-&gt;index, q);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (!vid &amp;&amp; enc-&gt;codec_type == AVMEDIA_TYPE_VIDEO) &#123;</span><br><span class="line">            <span class="keyword">float</span> fps;</span><br><span class="line"></span><br><span class="line">            frame_number = ost-&gt;frame_number;</span><br><span class="line">            fps = t &gt; <span class="number">1</span> ? frame_number / t : <span class="number">0</span>;</span><br><span class="line">            av_bprintf(&amp;buf, <span class="string">&quot;frame=%5d fps=%3.*f q=%3.1f &quot;</span>,</span><br><span class="line">                     frame_number, fps &lt; <span class="number">9.95</span>, fps, q);</span><br><span class="line">            av_bprintf(&amp;buf_script, <span class="string">&quot;frame=%d\n&quot;</span>, frame_number);</span><br><span class="line">            av_bprintf(&amp;buf_script, <span class="string">&quot;fps=%.2f\n&quot;</span>, fps);</span><br><span class="line">            av_bprintf(&amp;buf_script, <span class="string">&quot;stream_%d_%d_q=%.1f\n&quot;</span>,</span><br><span class="line">                       ost-&gt;file_index, ost-&gt;index, q);</span><br><span class="line">            <span class="keyword">if</span> (is_last_report)</span><br><span class="line">                av_bprintf(&amp;buf, <span class="string">&quot;L&quot;</span>);</span><br><span class="line">            <span class="keyword">if</span> (qp_hist) &#123;</span><br><span class="line">                <span class="keyword">int</span> j;</span><br><span class="line">                <span class="keyword">int</span> qp = lrintf(q);</span><br><span class="line">                <span class="keyword">if</span> (qp &gt;= <span class="number">0</span> &amp;&amp; qp &lt; FF_ARRAY_ELEMS(qp_histogram))</span><br><span class="line">                    qp_histogram[qp]++;</span><br><span class="line">                <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; <span class="number">32</span>; j++)</span><br><span class="line">                    av_bprintf(&amp;buf, <span class="string">&quot;%X&quot;</span>, av_log2(qp_histogram[j] + <span class="number">1</span>));</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> ((enc-&gt;flags &amp; AV_CODEC_FLAG_PSNR) &amp;&amp; (ost-&gt;pict_type != AV_PICTURE_TYPE_NONE || is_last_report)) &#123;</span><br><span class="line">                <span class="keyword">int</span> j;</span><br><span class="line">                <span class="keyword">double</span> error, error_sum = <span class="number">0</span>;</span><br><span class="line">                <span class="keyword">double</span> scale, scale_sum = <span class="number">0</span>;</span><br><span class="line">                <span class="keyword">double</span> p;</span><br><span class="line">                <span class="keyword">char</span> type[<span class="number">3</span>] = &#123; <span class="string">&#x27;Y&#x27;</span>,<span class="string">&#x27;U&#x27;</span>,<span class="string">&#x27;V&#x27;</span> &#125;;</span><br><span class="line">                av_bprintf(&amp;buf, <span class="string">&quot;PSNR=&quot;</span>);</span><br><span class="line">                <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; <span class="number">3</span>; j++) &#123;</span><br><span class="line">                    <span class="keyword">if</span> (is_last_report) &#123;</span><br><span class="line">                        error = enc-&gt;error[j];</span><br><span class="line">                        scale = enc-&gt;width * enc-&gt;height * <span class="number">255.0</span> * <span class="number">255.0</span> * frame_number;</span><br><span class="line">                    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                        error = ost-&gt;error[j];</span><br><span class="line">                        scale = enc-&gt;width * enc-&gt;height * <span class="number">255.0</span> * <span class="number">255.0</span>;</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="keyword">if</span> (j)</span><br><span class="line">                        scale /= <span class="number">4</span>;</span><br><span class="line">                    error_sum += error;</span><br><span class="line">                    scale_sum += scale;</span><br><span class="line">                    p = psnr(error / scale);</span><br><span class="line">                    av_bprintf(&amp;buf, <span class="string">&quot;%c:%2.2f &quot;</span>, type[j], p);</span><br><span class="line">                    av_bprintf(&amp;buf_script, <span class="string">&quot;stream_%d_%d_psnr_%c=%2.2f\n&quot;</span>,</span><br><span class="line">                               ost-&gt;file_index, ost-&gt;index, type[j] | <span class="number">32</span>, p);</span><br><span class="line">                &#125;</span><br><span class="line">                p = psnr(error_sum / scale_sum);</span><br><span class="line">                av_bprintf(&amp;buf, <span class="string">&quot;*:%2.2f &quot;</span>, psnr(error_sum / scale_sum));</span><br><span class="line">                av_bprintf(&amp;buf_script, <span class="string">&quot;stream_%d_%d_psnr_all=%2.2f\n&quot;</span>,</span><br><span class="line">                           ost-&gt;file_index, ost-&gt;index, p);</span><br><span class="line">            &#125;</span><br><span class="line">            vid = <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">/* compute min output value */</span></span><br><span class="line">        <span class="keyword">if</span> (av_stream_get_end_pts(ost-&gt;st) != AV_NOPTS_VALUE)</span><br><span class="line">            pts = FFMAX(pts, av_rescale_q(av_stream_get_end_pts(ost-&gt;st),</span><br><span class="line">                                          ost-&gt;st-&gt;time_base, AV_TIME_BASE_Q));</span><br><span class="line">        <span class="keyword">if</span> (is_last_report)</span><br><span class="line">            nb_frames_drop += ost-&gt;last_dropped;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    secs = FFABS(pts) / AV_TIME_BASE;</span><br><span class="line">    us = FFABS(pts) % AV_TIME_BASE;</span><br><span class="line">    mins = secs / <span class="number">60</span>;</span><br><span class="line">    secs %= <span class="number">60</span>;</span><br><span class="line">    hours = mins / <span class="number">60</span>;</span><br><span class="line">    mins %= <span class="number">60</span>;</span><br><span class="line">    hours_sign = (pts &lt; <span class="number">0</span>) ? <span class="string">&quot;-&quot;</span> : <span class="string">&quot;&quot;</span>;</span><br><span class="line"></span><br><span class="line">    bitrate = pts &amp;&amp; total_size &gt;= <span class="number">0</span> ? total_size * <span class="number">8</span> / (pts / <span class="number">1000.0</span>) : <span class="number">-1</span>;</span><br><span class="line">    speed = t != <span class="number">0.0</span> ? (<span class="keyword">double</span>)pts / AV_TIME_BASE / t : <span class="number">-1</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (total_size &lt; <span class="number">0</span>) av_bprintf(&amp;buf, <span class="string">&quot;size=N/A time=&quot;</span>);</span><br><span class="line">    <span class="keyword">else</span>                av_bprintf(&amp;buf, <span class="string">&quot;size=%8.0fkB time=&quot;</span>, total_size / <span class="number">1024.0</span>);</span><br><span class="line">    <span class="keyword">if</span> (pts == AV_NOPTS_VALUE) &#123;</span><br><span class="line">        av_bprintf(&amp;buf, <span class="string">&quot;N/A &quot;</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        av_bprintf(&amp;buf, <span class="string">&quot;%s%02d:%02d:%02d.%02d &quot;</span>,</span><br><span class="line">                   hours_sign, hours, mins, secs, (<span class="number">100</span> * us) / AV_TIME_BASE);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (bitrate &lt; <span class="number">0</span>) &#123;</span><br><span class="line">        av_bprintf(&amp;buf, <span class="string">&quot;bitrate=N/A&quot;</span>);</span><br><span class="line">        av_bprintf(&amp;buf_script, <span class="string">&quot;bitrate=N/A\n&quot;</span>);</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        av_bprintf(&amp;buf, <span class="string">&quot;bitrate=%6.1fkbits/s&quot;</span>, bitrate);</span><br><span class="line">        av_bprintf(&amp;buf_script, <span class="string">&quot;bitrate=%6.1fkbits/s\n&quot;</span>, bitrate);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (total_size &lt; <span class="number">0</span>) av_bprintf(&amp;buf_script, <span class="string">&quot;total_size=N/A\n&quot;</span>);</span><br><span class="line">    <span class="keyword">else</span>                av_bprintf(&amp;buf_script, <span class="string">&quot;total_size=%&quot;</span>PRId64<span class="string">&quot;\n&quot;</span>, total_size);</span><br><span class="line">    <span class="keyword">if</span> (pts == AV_NOPTS_VALUE) &#123;</span><br><span class="line">        av_bprintf(&amp;buf_script, <span class="string">&quot;out_time_us=N/A\n&quot;</span>);</span><br><span class="line">        av_bprintf(&amp;buf_script, <span class="string">&quot;out_time_ms=N/A\n&quot;</span>);</span><br><span class="line">        av_bprintf(&amp;buf_script, <span class="string">&quot;out_time=N/A\n&quot;</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        av_bprintf(&amp;buf_script, <span class="string">&quot;out_time_us=%&quot;</span>PRId64<span class="string">&quot;\n&quot;</span>, pts);</span><br><span class="line">        av_bprintf(&amp;buf_script, <span class="string">&quot;out_time_ms=%&quot;</span>PRId64<span class="string">&quot;\n&quot;</span>, pts);</span><br><span class="line">        av_bprintf(&amp;buf_script, <span class="string">&quot;out_time=%s%02d:%02d:%02d.%06d\n&quot;</span>,</span><br><span class="line">                   hours_sign, hours, mins, secs, us);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (nb_frames_dup || nb_frames_drop)</span><br><span class="line">        av_bprintf(&amp;buf, <span class="string">&quot; dup=%d drop=%d&quot;</span>, nb_frames_dup, nb_frames_drop);</span><br><span class="line">    av_bprintf(&amp;buf_script, <span class="string">&quot;dup_frames=%d\n&quot;</span>, nb_frames_dup);</span><br><span class="line">    av_bprintf(&amp;buf_script, <span class="string">&quot;drop_frames=%d\n&quot;</span>, nb_frames_drop);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (speed &lt; <span class="number">0</span>) &#123;</span><br><span class="line">        av_bprintf(&amp;buf, <span class="string">&quot; speed=N/A&quot;</span>);</span><br><span class="line">        av_bprintf(&amp;buf_script, <span class="string">&quot;speed=N/A\n&quot;</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        av_bprintf(&amp;buf, <span class="string">&quot; speed=%4.3gx&quot;</span>, speed);</span><br><span class="line">        av_bprintf(&amp;buf_script, <span class="string">&quot;speed=%4.3gx\n&quot;</span>, speed);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (print_stats || is_last_report) &#123;</span><br><span class="line">        <span class="keyword">const</span> <span class="keyword">char</span> end = is_last_report ? <span class="string">&#x27;\n&#x27;</span> : <span class="string">&#x27;\r&#x27;</span>;</span><br><span class="line">        <span class="keyword">if</span> (print_stats==<span class="number">1</span> &amp;&amp; AV_LOG_INFO &gt; av_log_get_level()) &#123;</span><br><span class="line">            <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">&quot;%s    %c&quot;</span>, buf.str, end);</span><br><span class="line">        &#125; <span class="keyword">else</span></span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;%s    %c&quot;</span>, buf.str, end);</span><br><span class="line"></span><br><span class="line">        fflush(<span class="built_in">stderr</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    av_bprint_finalize(&amp;buf, <span class="literal">NULL</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (progress_avio) &#123;</span><br><span class="line">        av_bprintf(&amp;buf_script, <span class="string">&quot;progress=%s\n&quot;</span>,</span><br><span class="line">                   is_last_report ? <span class="string">&quot;end&quot;</span> : <span class="string">&quot;continue&quot;</span>);</span><br><span class="line">        avio_write(progress_avio, buf_script.str,</span><br><span class="line">                   FFMIN(buf_script.len, buf_script.size - <span class="number">1</span>));</span><br><span class="line">        avio_flush(progress_avio);</span><br><span class="line">        av_bprint_finalize(&amp;buf_script, <span class="literal">NULL</span>);</span><br><span class="line">        <span class="keyword">if</span> (is_last_report) &#123;</span><br><span class="line">            <span class="keyword">if</span> ((ret = avio_closep(&amp;progress_avio)) &lt; <span class="number">0</span>)</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_ERROR,</span><br><span class="line">                       <span class="string">&quot;Error closing progress log, loss of information possible: %s\n&quot;</span>, av_err2str(ret));</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (is_last_report)</span><br><span class="line">        print_final_stats(total_size);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">ifilter_parameters_from_codecpar</span><span class="params">(InputFilter *ifilter, AVCodecParameters *par)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="comment">// We never got any input. Set a fake format, which will</span></span><br><span class="line">    <span class="comment">// come from libavformat.</span></span><br><span class="line">    ifilter-&gt;format                 = par-&gt;format;</span><br><span class="line">    ifilter-&gt;sample_rate            = par-&gt;sample_rate;</span><br><span class="line">    ifilter-&gt;channels               = par-&gt;channels;</span><br><span class="line">    ifilter-&gt;channel_layout         = par-&gt;channel_layout;</span><br><span class="line">    ifilter-&gt;width                  = par-&gt;width;</span><br><span class="line">    ifilter-&gt;height                 = par-&gt;height;</span><br><span class="line">    ifilter-&gt;sample_aspect_ratio    = par-&gt;sample_aspect_ratio;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">flush_encoders</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i, ret;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_streams; i++) &#123;</span><br><span class="line">        OutputStream   *ost = output_streams[i];</span><br><span class="line">        AVCodecContext *enc = ost-&gt;enc_ctx;</span><br><span class="line">        OutputFile      *of = output_files[ost-&gt;file_index];</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!ost-&gt;encoding_needed)</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// Try to enable encoding with no input frames.</span></span><br><span class="line">        <span class="comment">// Maybe we should just let encoding fail instead.</span></span><br><span class="line">        <span class="keyword">if</span> (!ost-&gt;initialized) &#123;</span><br><span class="line">            FilterGraph *fg = ost-&gt;filter-&gt;graph;</span><br><span class="line">            <span class="keyword">char</span> error[<span class="number">1024</span>] = <span class="string">&quot;&quot;</span>;</span><br><span class="line"></span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_WARNING,</span><br><span class="line">                   <span class="string">&quot;Finishing stream %d:%d without any data written to it.\n&quot;</span>,</span><br><span class="line">                   ost-&gt;file_index, ost-&gt;st-&gt;index);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (ost-&gt;filter &amp;&amp; !fg-&gt;graph) &#123;</span><br><span class="line">                <span class="keyword">int</span> x;</span><br><span class="line">                <span class="keyword">for</span> (x = <span class="number">0</span>; x &lt; fg-&gt;nb_inputs; x++) &#123;</span><br><span class="line">                    InputFilter *ifilter = fg-&gt;inputs[x];</span><br><span class="line">                    <span class="keyword">if</span> (ifilter-&gt;format &lt; <span class="number">0</span>)</span><br><span class="line">                        ifilter_parameters_from_codecpar(ifilter, ifilter-&gt;ist-&gt;st-&gt;codecpar);</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                <span class="keyword">if</span> (!ifilter_has_all_input_formats(fg))</span><br><span class="line">                    <span class="keyword">continue</span>;</span><br><span class="line"></span><br><span class="line">                ret = configure_filtergraph(fg);</span><br><span class="line">                <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                    av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;Error configuring filter graph\n&quot;</span>);</span><br><span class="line">                    exit_program(<span class="number">1</span>);</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                finish_output_stream(ost);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            ret = init_output_stream(ost, error, <span class="keyword">sizeof</span>(error));</span><br><span class="line">            <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;Error initializing output stream %d:%d -- %s\n&quot;</span>,</span><br><span class="line">                       ost-&gt;file_index, ost-&gt;index, error);</span><br><span class="line">                exit_program(<span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (enc-&gt;codec_type == AVMEDIA_TYPE_AUDIO &amp;&amp; enc-&gt;frame_size &lt;= <span class="number">1</span>)</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (enc-&gt;codec_type != AVMEDIA_TYPE_VIDEO &amp;&amp; enc-&gt;codec_type != AVMEDIA_TYPE_AUDIO)</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (;;) &#123;</span><br><span class="line">            <span class="keyword">const</span> <span class="keyword">char</span> *desc = <span class="literal">NULL</span>;</span><br><span class="line">            AVPacket pkt;</span><br><span class="line">            <span class="keyword">int</span> pkt_size;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">switch</span> (enc-&gt;codec_type) &#123;</span><br><span class="line">            <span class="keyword">case</span> AVMEDIA_TYPE_AUDIO:</span><br><span class="line">                desc   = <span class="string">&quot;audio&quot;</span>;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> AVMEDIA_TYPE_VIDEO:</span><br><span class="line">                desc   = <span class="string">&quot;video&quot;</span>;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">default</span>:</span><br><span class="line">                av_assert0(<span class="number">0</span>);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            av_init_packet(&amp;pkt);</span><br><span class="line">            pkt.data = <span class="literal">NULL</span>;</span><br><span class="line">            pkt.size = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">            update_benchmark(<span class="literal">NULL</span>);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">while</span> ((ret = avcodec_receive_packet(enc, &amp;pkt)) == AVERROR(EAGAIN)) &#123;</span><br><span class="line">                ret = avcodec_send_frame(enc, <span class="literal">NULL</span>);</span><br><span class="line">                <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                    av_log(<span class="literal">NULL</span>, AV_LOG_FATAL, <span class="string">&quot;%s encoding failed: %s\n&quot;</span>,</span><br><span class="line">                           desc,</span><br><span class="line">                           av_err2str(ret));</span><br><span class="line">                    exit_program(<span class="number">1</span>);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            update_benchmark(<span class="string">&quot;flush_%s %d.%d&quot;</span>, desc, ost-&gt;file_index, ost-&gt;index);</span><br><span class="line">            <span class="keyword">if</span> (ret &lt; <span class="number">0</span> &amp;&amp; ret != AVERROR_EOF) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_FATAL, <span class="string">&quot;%s encoding failed: %s\n&quot;</span>,</span><br><span class="line">                       desc,</span><br><span class="line">                       av_err2str(ret));</span><br><span class="line">                exit_program(<span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (ost-&gt;logfile &amp;&amp; enc-&gt;stats_out) &#123;</span><br><span class="line">                <span class="built_in">fprintf</span>(ost-&gt;logfile, <span class="string">&quot;%s&quot;</span>, enc-&gt;stats_out);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (ret == AVERROR_EOF) &#123;</span><br><span class="line">                output_packet(of, &amp;pkt, ost, <span class="number">1</span>);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (ost-&gt;finished &amp; MUXER_FINISHED) &#123;</span><br><span class="line">                av_packet_unref(&amp;pkt);</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            av_packet_rescale_ts(&amp;pkt, enc-&gt;time_base, ost-&gt;mux_timebase);</span><br><span class="line">            pkt_size = pkt.size;</span><br><span class="line">            output_packet(of, &amp;pkt, ost, <span class="number">0</span>);</span><br><span class="line">            <span class="keyword">if</span> (ost-&gt;enc_ctx-&gt;codec_type == AVMEDIA_TYPE_VIDEO &amp;&amp; vstats_filename) &#123;</span><br><span class="line">                do_video_stats(ost, pkt_size);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * Check whether a packet from ist should be written into ost at this time</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">check_output_constraints</span><span class="params">(InputStream *ist, OutputStream *ost)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    OutputFile *of = output_files[ost-&gt;file_index];</span><br><span class="line">    <span class="keyword">int</span> ist_index  = input_files[ist-&gt;file_index]-&gt;ist_index + ist-&gt;st-&gt;index;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ost-&gt;source_index != ist_index)</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ost-&gt;finished)</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (of-&gt;start_time != AV_NOPTS_VALUE &amp;&amp; ist-&gt;pts &lt; of-&gt;start_time)</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">do_streamcopy</span><span class="params">(InputStream *ist, OutputStream *ost, <span class="keyword">const</span> AVPacket *pkt)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    OutputFile *of = output_files[ost-&gt;file_index];</span><br><span class="line">    InputFile   *f = input_files [ist-&gt;file_index];</span><br><span class="line">    <span class="keyword">int64_t</span> start_time = (of-&gt;start_time == AV_NOPTS_VALUE) ? <span class="number">0</span> : of-&gt;start_time;</span><br><span class="line">    <span class="keyword">int64_t</span> ost_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ost-&gt;mux_timebase);</span><br><span class="line">    AVPacket opkt = &#123; <span class="number">0</span> &#125;;</span><br><span class="line"></span><br><span class="line">    av_init_packet(&amp;opkt);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// EOF: flush output bitstream filters.</span></span><br><span class="line">    <span class="keyword">if</span> (!pkt) &#123;</span><br><span class="line">        output_packet(of, &amp;opkt, ost, <span class="number">1</span>);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> ((!ost-&gt;frame_number &amp;&amp; !(pkt-&gt;flags &amp; AV_PKT_FLAG_KEY)) &amp;&amp;</span><br><span class="line">        !ost-&gt;copy_initial_nonkeyframes)</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!ost-&gt;frame_number &amp;&amp; !ost-&gt;copy_prior_start) &#123;</span><br><span class="line">        <span class="keyword">int64_t</span> comp_start = start_time;</span><br><span class="line">        <span class="keyword">if</span> (copy_ts &amp;&amp; f-&gt;start_time != AV_NOPTS_VALUE)</span><br><span class="line">            comp_start = FFMAX(start_time, f-&gt;start_time + f-&gt;ts_offset);</span><br><span class="line">        <span class="keyword">if</span> (pkt-&gt;pts == AV_NOPTS_VALUE ?</span><br><span class="line">            ist-&gt;pts &lt; comp_start :</span><br><span class="line">            <span class="comment">// 由微妙转成AVStream time_base</span></span><br><span class="line">            pkt-&gt;pts &lt; av_rescale_q(comp_start, AV_TIME_BASE_Q, ist-&gt;st-&gt;time_base))</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (of-&gt;recording_time != INT64_MAX &amp;&amp;</span><br><span class="line">        ist-&gt;pts &gt;= of-&gt;recording_time + start_time) &#123;</span><br><span class="line">        close_output_stream(ost);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (f-&gt;recording_time != INT64_MAX) &#123;</span><br><span class="line">        start_time = f-&gt;ctx-&gt;start_time;</span><br><span class="line">        <span class="keyword">if</span> (f-&gt;start_time != AV_NOPTS_VALUE &amp;&amp; copy_ts)</span><br><span class="line">            start_time += f-&gt;start_time;</span><br><span class="line">        <span class="keyword">if</span> (ist-&gt;pts &gt;= f-&gt;recording_time + start_time) &#123;</span><br><span class="line">            close_output_stream(ost);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* force the input stream PTS */</span></span><br><span class="line">    <span class="keyword">if</span> (ost-&gt;enc_ctx-&gt;codec_type == AVMEDIA_TYPE_VIDEO)</span><br><span class="line">        ost-&gt;sync_opts++;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (pkt-&gt;pts != AV_NOPTS_VALUE)</span><br><span class="line">        opkt.pts = av_rescale_q(pkt-&gt;pts, ist-&gt;st-&gt;time_base, ost-&gt;mux_timebase) - ost_tb_start_time;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">        opkt.pts = AV_NOPTS_VALUE;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (pkt-&gt;dts == AV_NOPTS_VALUE)</span><br><span class="line">        opkt.dts = av_rescale_q(ist-&gt;dts, AV_TIME_BASE_Q, ost-&gt;mux_timebase);</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">        opkt.dts = av_rescale_q(pkt-&gt;dts, ist-&gt;st-&gt;time_base, ost-&gt;mux_timebase);</span><br><span class="line">    opkt.dts -= ost_tb_start_time;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ost-&gt;st-&gt;codecpar-&gt;codec_type == AVMEDIA_TYPE_AUDIO &amp;&amp; pkt-&gt;dts != AV_NOPTS_VALUE) &#123;</span><br><span class="line">        <span class="keyword">int</span> duration = av_get_audio_frame_duration(ist-&gt;dec_ctx, pkt-&gt;size);</span><br><span class="line">        <span class="keyword">if</span>(!duration)</span><br><span class="line">            duration = ist-&gt;dec_ctx-&gt;frame_size;</span><br><span class="line">        opkt.dts = opkt.pts = av_rescale_delta(ist-&gt;st-&gt;time_base, pkt-&gt;dts,</span><br><span class="line">                                               (AVRational)&#123;<span class="number">1</span>, ist-&gt;dec_ctx-&gt;sample_rate&#125;, duration, &amp;ist-&gt;filter_in_rescale_delta_last,</span><br><span class="line">                                               ost-&gt;mux_timebase) - ost_tb_start_time;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    opkt.duration = av_rescale_q(pkt-&gt;duration, ist-&gt;st-&gt;time_base, ost-&gt;mux_timebase);</span><br><span class="line"></span><br><span class="line">    opkt.flags    = pkt-&gt;flags;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (pkt-&gt;buf) &#123;</span><br><span class="line">        opkt.buf = av_buffer_ref(pkt-&gt;buf);</span><br><span class="line">        <span class="keyword">if</span> (!opkt.buf)</span><br><span class="line">            exit_program(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    opkt.data = pkt-&gt;data;</span><br><span class="line">    opkt.size = pkt-&gt;size;</span><br><span class="line"></span><br><span class="line">    av_copy_packet_side_data(&amp;opkt, pkt);</span><br><span class="line"></span><br><span class="line">    output_packet(of, &amp;opkt, ost, <span class="number">0</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">guess_input_channel_layout</span><span class="params">(InputStream *ist)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    AVCodecContext *dec = ist-&gt;dec_ctx;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!dec-&gt;channel_layout) &#123;</span><br><span class="line">        <span class="keyword">char</span> layout_name[<span class="number">256</span>];</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (dec-&gt;channels &gt; ist-&gt;guess_layout_max)</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        dec-&gt;channel_layout = av_get_default_channel_layout(dec-&gt;channels);</span><br><span class="line">        <span class="keyword">if</span> (!dec-&gt;channel_layout)</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        av_get_channel_layout_string(layout_name, <span class="keyword">sizeof</span>(layout_name),</span><br><span class="line">                                     dec-&gt;channels, dec-&gt;channel_layout);</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_WARNING, <span class="string">&quot;Guessed Channel Layout for Input Stream &quot;</span></span><br><span class="line">               <span class="string">&quot;#%d.%d : %s\n&quot;</span>, ist-&gt;file_index, ist-&gt;st-&gt;index, layout_name);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">check_decode_result</span><span class="params">(InputStream *ist, <span class="keyword">int</span> *got_output, <span class="keyword">int</span> ret)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (*got_output || ret&lt;<span class="number">0</span>)</span><br><span class="line">        decode_error_stat[ret&lt;<span class="number">0</span>] ++;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span> &amp;&amp; exit_on_error)</span><br><span class="line">        exit_program(<span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (*got_output &amp;&amp; ist) &#123;</span><br><span class="line">        <span class="keyword">if</span> (ist-&gt;decoded_frame-&gt;decode_error_flags || (ist-&gt;decoded_frame-&gt;flags &amp; AV_FRAME_FLAG_CORRUPT)) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING,</span><br><span class="line">                   <span class="string">&quot;%s: corrupt decoded frame in stream %d\n&quot;</span>, input_files[ist-&gt;file_index]-&gt;ctx-&gt;url, ist-&gt;st-&gt;index);</span><br><span class="line">            <span class="keyword">if</span> (exit_on_error)</span><br><span class="line">                exit_program(<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// Filters can be configured only if the formats of all inputs are known.</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">ifilter_has_all_input_formats</span><span class="params">(FilterGraph *fg)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i;</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; fg-&gt;nb_inputs; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (fg-&gt;inputs[i]-&gt;format &lt; <span class="number">0</span> &amp;&amp; (fg-&gt;inputs[i]-&gt;type == AVMEDIA_TYPE_AUDIO ||</span><br><span class="line">                                          fg-&gt;inputs[i]-&gt;type == AVMEDIA_TYPE_VIDEO))</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">  做一些参数的检查，包括过滤器链表有没有初始化，没有的化先初始化，找到处理该包的第一个过滤器，</span></span><br><span class="line"><span class="comment">  第一个过滤器一定是buffersrc， ffmpeg自带的，由这个过滤器传给自己ffmpeg 参数带的第一个过滤器，</span></span><br><span class="line"><span class="comment">  这相当于一个入口</span></span><br><span class="line"><span class="comment"> * @brief ifilter_send_frame</span></span><br><span class="line"><span class="comment"> * @param ifilter</span></span><br><span class="line"><span class="comment"> * @param frame</span></span><br><span class="line"><span class="comment"> * @return</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">ifilter_send_frame</span><span class="params">(InputFilter *ifilter, AVFrame *frame)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    FilterGraph *fg = ifilter-&gt;graph;</span><br><span class="line">    <span class="keyword">int</span> need_reinit, ret, i;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* determine if the parameters for this input changed */</span></span><br><span class="line">    need_reinit = ifilter-&gt;format != frame-&gt;format;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">switch</span> (ifilter-&gt;ist-&gt;st-&gt;codecpar-&gt;codec_type) &#123;</span><br><span class="line">    <span class="keyword">case</span> AVMEDIA_TYPE_AUDIO:</span><br><span class="line">        need_reinit |= ifilter-&gt;sample_rate    != frame-&gt;sample_rate ||</span><br><span class="line">                       ifilter-&gt;channels       != frame-&gt;channels ||</span><br><span class="line">                       ifilter-&gt;channel_layout != frame-&gt;channel_layout;</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> AVMEDIA_TYPE_VIDEO:</span><br><span class="line">        need_reinit |= ifilter-&gt;width  != frame-&gt;width ||</span><br><span class="line">                       ifilter-&gt;height != frame-&gt;height;</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!ifilter-&gt;ist-&gt;reinit_filters &amp;&amp; fg-&gt;graph)</span><br><span class="line">        need_reinit = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!!ifilter-&gt;hw_frames_ctx != !!frame-&gt;hw_frames_ctx ||</span><br><span class="line">        (ifilter-&gt;hw_frames_ctx &amp;&amp; ifilter-&gt;hw_frames_ctx-&gt;data != frame-&gt;hw_frames_ctx-&gt;data))</span><br><span class="line">        need_reinit = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (need_reinit) &#123;      <span class="comment">// 初始化filter</span></span><br><span class="line">        ret = ifilter_parameters_from_frame(ifilter, frame);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* (re)init the graph if possible, otherwise buffer the frame and return */</span></span><br><span class="line">    <span class="keyword">if</span> (need_reinit || !fg-&gt;graph) &#123;</span><br><span class="line">        <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; fg-&gt;nb_inputs; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (!ifilter_has_all_input_formats(fg)) &#123;</span><br><span class="line">                AVFrame *tmp = av_frame_clone(frame);</span><br><span class="line">                <span class="keyword">if</span> (!tmp)</span><br><span class="line">                    <span class="keyword">return</span> AVERROR(ENOMEM);</span><br><span class="line">                av_frame_unref(frame);</span><br><span class="line"></span><br><span class="line">                <span class="keyword">if</span> (!av_fifo_space(ifilter-&gt;frame_queue)) &#123;</span><br><span class="line">                    ret = av_fifo_realloc2(ifilter-&gt;frame_queue, <span class="number">2</span> * av_fifo_size(ifilter-&gt;frame_queue));</span><br><span class="line">                    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                        av_frame_free(&amp;tmp);</span><br><span class="line">                        <span class="keyword">return</span> ret;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">                av_fifo_generic_write(ifilter-&gt;frame_queue, &amp;tmp, <span class="keyword">sizeof</span>(tmp), <span class="literal">NULL</span>);</span><br><span class="line">                <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        ret = reap_filters(<span class="number">1</span>);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span> &amp;&amp; ret != AVERROR_EOF) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;Error while filtering: %s\n&quot;</span>, av_err2str(ret));</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        ret = configure_filtergraph(fg);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;Error reinitializing filters!\n&quot;</span>);</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//frame数据的控制权交给了av_buffersrc_add_frame_flags，然后外部的frame被reset</span></span><br><span class="line">    ret = av_buffersrc_add_frame_flags(ifilter-&gt;filter, frame, AV_BUFFERSRC_FLAG_PUSH);</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">if</span> (ret != AVERROR_EOF)</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;Error while filtering: %s\n&quot;</span>, av_err2str(ret));</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">ifilter_send_eof</span><span class="params">(InputFilter *ifilter, <span class="keyword">int64_t</span> pts)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> ret;</span><br><span class="line"></span><br><span class="line">    ifilter-&gt;eof = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ifilter-&gt;filter) &#123;</span><br><span class="line">        ret = av_buffersrc_close(ifilter-&gt;filter, pts, AV_BUFFERSRC_FLAG_PUSH);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="comment">// the filtergraph was never configured</span></span><br><span class="line">        <span class="keyword">if</span> (ifilter-&gt;format &lt; <span class="number">0</span>)</span><br><span class="line">            ifilter_parameters_from_codecpar(ifilter, ifilter-&gt;ist-&gt;st-&gt;codecpar);</span><br><span class="line">        <span class="keyword">if</span> (ifilter-&gt;format &lt; <span class="number">0</span> &amp;&amp; (ifilter-&gt;type == AVMEDIA_TYPE_AUDIO || ifilter-&gt;type == AVMEDIA_TYPE_VIDEO)) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;Cannot determine format of input stream %d:%d after EOF\n&quot;</span>, ifilter-&gt;ist-&gt;file_index, ifilter-&gt;ist-&gt;st-&gt;index);</span><br><span class="line">            <span class="keyword">return</span> AVERROR_INVALIDDATA;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// This does not quite work like avcodec_decode_audio4/avcodec_decode_video2.</span></span><br><span class="line"><span class="comment">// There is the following difference: if you got a frame, you must call</span></span><br><span class="line"><span class="comment">// it again with pkt=NULL. pkt==NULL is treated differently from pkt-&gt;size==0</span></span><br><span class="line"><span class="comment">// (pkt==NULL means get more output, pkt-&gt;size==0 is a flush/drain packet)</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">decode</span><span class="params">(AVCodecContext *avctx, AVFrame *frame, <span class="keyword">int</span> *got_frame, AVPacket *pkt)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> ret;</span><br><span class="line"></span><br><span class="line">    *got_frame = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">if</span> (pkt) &#123;</span><br><span class="line">        ret = avcodec_send_packet(avctx, pkt);</span><br><span class="line">        <span class="comment">// In particular, we don&#x27;t expect AVERROR(EAGAIN), because we read all</span></span><br><span class="line">        <span class="comment">// decoded frames with avcodec_receive_frame() until done.</span></span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span> &amp;&amp; ret != AVERROR_EOF)</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    ret = avcodec_receive_frame(avctx, frame);</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span> &amp;&amp; ret != AVERROR(EAGAIN))</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    <span class="keyword">if</span> (ret &gt;= <span class="number">0</span>)</span><br><span class="line">        *got_frame = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">send_frame_to_filters</span><span class="params">(InputStream *ist, AVFrame *decoded_frame)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i, ret;</span><br><span class="line">    AVFrame *f;</span><br><span class="line"></span><br><span class="line">    av_assert1(ist-&gt;nb_filters &gt; <span class="number">0</span>); <span class="comment">/* ensure ret is initialized */</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; ist-&gt;nb_filters; i++) &#123; <span class="comment">// 可能接入多个filter，目前我们只看一个的</span></span><br><span class="line">        <span class="keyword">if</span> (i &lt; ist-&gt;nb_filters - <span class="number">1</span>) &#123;</span><br><span class="line">            f = ist-&gt;filter_frame;</span><br><span class="line">            ret = av_frame_ref(f, decoded_frame);</span><br><span class="line">            <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span></span><br><span class="line">            f = decoded_frame;  <span class="comment">// 发送到filter</span></span><br><span class="line">        <span class="comment">// ist-&gt;filters[0]-&gt;graph-&gt;graph-&gt;filters[n]</span></span><br><span class="line">        ret = ifilter_send_frame(ist-&gt;filters[i], f);</span><br><span class="line">        <span class="keyword">if</span> (ret == AVERROR_EOF)</span><br><span class="line">            ret = <span class="number">0</span>; <span class="comment">/* ignore */</span></span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_ERROR,</span><br><span class="line">                   <span class="string">&quot;Failed to inject frame into filter network: %s\n&quot;</span>, av_err2str(ret));</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> ret;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">decode_audio</span><span class="params">(InputStream *ist, AVPacket *pkt, <span class="keyword">int</span> *got_output,</span></span></span><br><span class="line"><span class="function"><span class="params">                        <span class="keyword">int</span> *decode_failed)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    AVFrame *decoded_frame;</span><br><span class="line">    AVCodecContext *avctx = ist-&gt;dec_ctx;</span><br><span class="line">    <span class="keyword">int</span> ret, err = <span class="number">0</span>;</span><br><span class="line">    AVRational decoded_frame_tb;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!ist-&gt;decoded_frame &amp;&amp; !(ist-&gt;decoded_frame = av_frame_alloc()))</span><br><span class="line">        <span class="keyword">return</span> AVERROR(ENOMEM);</span><br><span class="line">    <span class="keyword">if</span> (!ist-&gt;filter_frame &amp;&amp; !(ist-&gt;filter_frame = av_frame_alloc()))</span><br><span class="line">        <span class="keyword">return</span> AVERROR(ENOMEM);</span><br><span class="line">    decoded_frame = ist-&gt;decoded_frame;</span><br><span class="line"></span><br><span class="line">    update_benchmark(<span class="literal">NULL</span>);</span><br><span class="line">    ret = decode(avctx, decoded_frame, got_output, pkt);</span><br><span class="line">    update_benchmark(<span class="string">&quot;decode_audio %d.%d&quot;</span>, ist-&gt;file_index, ist-&gt;st-&gt;index);</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">        *decode_failed = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ret &gt;= <span class="number">0</span> &amp;&amp; avctx-&gt;sample_rate &lt;= <span class="number">0</span>) &#123;</span><br><span class="line">        av_log(avctx, AV_LOG_ERROR, <span class="string">&quot;Sample rate %d invalid\n&quot;</span>, avctx-&gt;sample_rate);</span><br><span class="line">        ret = AVERROR_INVALIDDATA;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ret != AVERROR_EOF)</span><br><span class="line">        check_decode_result(ist, got_output, ret);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!*got_output || ret &lt; <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line"></span><br><span class="line">    ist-&gt;samples_decoded += decoded_frame-&gt;nb_samples;  <span class="comment">// 计算samples数量</span></span><br><span class="line">    ist-&gt;frames_decoded++;  <span class="comment">// 计算帧数量</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/* increment next_dts to use for the case where the input stream does not</span></span><br><span class="line"><span class="comment">       have timestamps or there are multiple frames in the packet */</span></span><br><span class="line">    ist-&gt;next_pts += ((<span class="keyword">int64_t</span>)AV_TIME_BASE * decoded_frame-&gt;nb_samples) /</span><br><span class="line">                     avctx-&gt;sample_rate;    <span class="comment">// 计算下一帧pts</span></span><br><span class="line">    ist-&gt;next_dts += ((<span class="keyword">int64_t</span>)AV_TIME_BASE * decoded_frame-&gt;nb_samples) /</span><br><span class="line">                     avctx-&gt;sample_rate;     <span class="comment">// 计算下一帧dts</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (decoded_frame-&gt;pts != AV_NOPTS_VALUE) &#123;</span><br><span class="line">        decoded_frame_tb   = ist-&gt;st-&gt;time_base;</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (pkt &amp;&amp; pkt-&gt;pts != AV_NOPTS_VALUE) &#123;</span><br><span class="line">        decoded_frame-&gt;pts = pkt-&gt;pts;</span><br><span class="line">        decoded_frame_tb   = ist-&gt;st-&gt;time_base;</span><br><span class="line">    &#125;<span class="keyword">else</span> &#123;</span><br><span class="line">        decoded_frame-&gt;pts = ist-&gt;dts;</span><br><span class="line">        decoded_frame_tb   = AV_TIME_BASE_Q;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (decoded_frame-&gt;pts != AV_NOPTS_VALUE)</span><br><span class="line">        decoded_frame-&gt;pts = av_rescale_delta(decoded_frame_tb, decoded_frame-&gt;pts,</span><br><span class="line">                                              (AVRational)&#123;<span class="number">1</span>, avctx-&gt;sample_rate&#125;, decoded_frame-&gt;nb_samples, &amp;ist-&gt;filter_in_rescale_delta_last,</span><br><span class="line">                                              (AVRational)&#123;<span class="number">1</span>, avctx-&gt;sample_rate&#125;);</span><br><span class="line">    ist-&gt;nb_samples = decoded_frame-&gt;nb_samples;</span><br><span class="line">    err = send_frame_to_filters(ist, decoded_frame);    <span class="comment">// 先把帧发送到filter</span></span><br><span class="line"></span><br><span class="line">    av_frame_unref(ist-&gt;filter_frame);</span><br><span class="line">    av_frame_unref(decoded_frame);</span><br><span class="line">    <span class="keyword">return</span> err &lt; <span class="number">0</span> ? err : ret;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//解码视频包，将解码的包交给filter处理</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">decode_video</span><span class="params">(InputStream *ist, AVPacket *pkt, <span class="keyword">int</span> *got_output, <span class="keyword">int64_t</span> *duration_pts,</span></span></span><br><span class="line"><span class="function"><span class="params">                        <span class="keyword">int</span> eof, <span class="keyword">int</span> *decode_failed)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    AVFrame *decoded_frame; <span class="comment">// 解码后的帧</span></span><br><span class="line">    <span class="keyword">int</span> i, ret = <span class="number">0</span>, err = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int64_t</span> best_effort_timestamp;</span><br><span class="line">    <span class="keyword">int64_t</span> dts = AV_NOPTS_VALUE;</span><br><span class="line">    AVPacket avpkt;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// With fate-indeo3-2, we&#x27;re getting 0-sized packets before EOF for some</span></span><br><span class="line">    <span class="comment">// reason. This seems like a semi-critical bug. Don&#x27;t trigger EOF, and</span></span><br><span class="line">    <span class="comment">// skip the packet.</span></span><br><span class="line">    <span class="keyword">if</span> (!eof &amp;&amp; pkt &amp;&amp; pkt-&gt;size == <span class="number">0</span>)  <span class="comment">// 判断pkt是否有效</span></span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="comment">// frame为null的时候则av_frame_alloc</span></span><br><span class="line">    <span class="keyword">if</span> (!ist-&gt;decoded_frame &amp;&amp; !(ist-&gt;decoded_frame = av_frame_alloc()))</span><br><span class="line">        <span class="keyword">return</span> AVERROR(ENOMEM); <span class="comment">// 分配内存失败</span></span><br><span class="line">    <span class="keyword">if</span> (!ist-&gt;filter_frame &amp;&amp; !(ist-&gt;filter_frame = av_frame_alloc()))</span><br><span class="line">        <span class="keyword">return</span> AVERROR(ENOMEM);<span class="comment">// 分配内存失败</span></span><br><span class="line">    decoded_frame = ist-&gt;decoded_frame;</span><br><span class="line">    <span class="keyword">if</span> (ist-&gt;dts != AV_NOPTS_VALUE) &#123;</span><br><span class="line">        dts = av_rescale_q(ist-&gt;dts, AV_TIME_BASE_Q, ist-&gt;st-&gt;time_base);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (pkt) &#123;</span><br><span class="line">        avpkt = *pkt;</span><br><span class="line">        avpkt.dts = dts; <span class="comment">// ffmpeg.c probably shouldn&#x27;t do this，解码的时候还是转成了st-&gt;time_base</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// The old code used to set dts on the drain packet, which does not work</span></span><br><span class="line">    <span class="comment">// with the new API anymore.</span></span><br><span class="line">    <span class="keyword">if</span> (eof) &#123;</span><br><span class="line">        <span class="keyword">void</span> *<span class="keyword">new</span> = av_realloc_array(ist-&gt;dts_buffer, ist-&gt;nb_dts_buffer + <span class="number">1</span>, <span class="keyword">sizeof</span>(ist-&gt;dts_buffer[<span class="number">0</span>]));</span><br><span class="line">        <span class="keyword">if</span> (!<span class="keyword">new</span>)</span><br><span class="line">            <span class="keyword">return</span> AVERROR(ENOMEM);</span><br><span class="line">        ist-&gt;dts_buffer = <span class="keyword">new</span>;</span><br><span class="line">        ist-&gt;dts_buffer[ist-&gt;nb_dts_buffer++] = dts;   <span class="comment">// 存储dts</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    update_benchmark(<span class="literal">NULL</span>);</span><br><span class="line">    ret = decode(ist-&gt;dec_ctx, decoded_frame, got_output, pkt ? &amp;avpkt : <span class="literal">NULL</span>);</span><br><span class="line">    update_benchmark(<span class="string">&quot;decode_video %d.%d&quot;</span>, ist-&gt;file_index, ist-&gt;st-&gt;index);</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">        *decode_failed = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// The following line may be required in some cases where there is no parser</span></span><br><span class="line">    <span class="comment">// or the parser does not has_b_frames correctly</span></span><br><span class="line">    <span class="keyword">if</span> (ist-&gt;st-&gt;codecpar-&gt;video_delay &lt; ist-&gt;dec_ctx-&gt;has_b_frames) &#123;</span><br><span class="line">        <span class="keyword">if</span> (ist-&gt;dec_ctx-&gt;codec_id == AV_CODEC_ID_H264) &#123;</span><br><span class="line">            ist-&gt;st-&gt;codecpar-&gt;video_delay = ist-&gt;dec_ctx-&gt;has_b_frames;  <span class="comment">// 存在B帧时延迟</span></span><br><span class="line">        &#125; <span class="keyword">else</span></span><br><span class="line">            av_log(ist-&gt;dec_ctx, AV_LOG_WARNING,</span><br><span class="line">                   <span class="string">&quot;video_delay is larger in decoder than demuxer %d &gt; %d.\n&quot;</span></span><br><span class="line">                   <span class="string">&quot;If you want to help, upload a sample &quot;</span></span><br><span class="line">                   <span class="string">&quot;of this file to ftp://upload.ffmpeg.org/incoming/ &quot;</span></span><br><span class="line">                   <span class="string">&quot;and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)\n&quot;</span>,</span><br><span class="line">                   ist-&gt;dec_ctx-&gt;has_b_frames,</span><br><span class="line">                   ist-&gt;st-&gt;codecpar-&gt;video_delay);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ret != AVERROR_EOF)</span><br><span class="line">        check_decode_result(ist, got_output, ret);  <span class="comment">// 只是作解码结果统计</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (*got_output &amp;&amp; ret &gt;= <span class="number">0</span>) &#123;  <span class="comment">// 检测解码后的宽高、格式是否和dec_ctx预计的一致</span></span><br><span class="line">        <span class="keyword">if</span> (ist-&gt;dec_ctx-&gt;width  != decoded_frame-&gt;width ||</span><br><span class="line">            ist-&gt;dec_ctx-&gt;height != decoded_frame-&gt;height ||</span><br><span class="line">            ist-&gt;dec_ctx-&gt;pix_fmt != decoded_frame-&gt;format) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_DEBUG, <span class="string">&quot;Frame parameters mismatch context %d,%d,%d != %d,%d,%d\n&quot;</span>,</span><br><span class="line">                decoded_frame-&gt;width,</span><br><span class="line">                decoded_frame-&gt;height,</span><br><span class="line">                decoded_frame-&gt;format,</span><br><span class="line">                ist-&gt;dec_ctx-&gt;width,</span><br><span class="line">                ist-&gt;dec_ctx-&gt;height,</span><br><span class="line">                ist-&gt;dec_ctx-&gt;pix_fmt);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!*got_output || ret &lt; <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(ist-&gt;top_field_first&gt;=<span class="number">0</span>)</span><br><span class="line">        decoded_frame-&gt;top_field_first = ist-&gt;top_field_first;</span><br><span class="line"></span><br><span class="line">    ist-&gt;frames_decoded++;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ist-&gt;hwaccel_retrieve_data &amp;&amp; decoded_frame-&gt;format == ist-&gt;hwaccel_pix_fmt) &#123;</span><br><span class="line">        err = ist-&gt;hwaccel_retrieve_data(ist-&gt;dec_ctx, decoded_frame);</span><br><span class="line">        <span class="keyword">if</span> (err &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">goto</span> fail;</span><br><span class="line">    &#125;</span><br><span class="line">    ist-&gt;hwaccel_retrieved_pix_fmt = decoded_frame-&gt;format;</span><br><span class="line"></span><br><span class="line">    best_effort_timestamp= decoded_frame-&gt;best_effort_timestamp;</span><br><span class="line">    *duration_pts = decoded_frame-&gt;pkt_duration;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ist-&gt;framerate.num)     <span class="comment">// 这里设置了强制帧率 比如 -r 20 -i  5.mp4 5.flv 强制将输入按20帧每秒进行处理</span></span><br><span class="line">        best_effort_timestamp = ist-&gt;cfr_next_pts++;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (eof &amp;&amp; best_effort_timestamp == AV_NOPTS_VALUE &amp;&amp; ist-&gt;nb_dts_buffer &gt; <span class="number">0</span>) &#123;</span><br><span class="line">        best_effort_timestamp = ist-&gt;dts_buffer[<span class="number">0</span>];</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; ist-&gt;nb_dts_buffer - <span class="number">1</span>; i++)</span><br><span class="line">            ist-&gt;dts_buffer[i] = ist-&gt;dts_buffer[i + <span class="number">1</span>];</span><br><span class="line">        ist-&gt;nb_dts_buffer--;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(best_effort_timestamp != AV_NOPTS_VALUE) &#123;</span><br><span class="line">        <span class="keyword">int64_t</span> ts = av_rescale_q(decoded_frame-&gt;pts = best_effort_timestamp, ist-&gt;st-&gt;time_base, AV_TIME_BASE_Q);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ts != AV_NOPTS_VALUE)</span><br><span class="line">            ist-&gt;next_pts = ist-&gt;pts = ts;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (debug_ts) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;decoder -&gt; ist_index:%d type:video &quot;</span></span><br><span class="line">               <span class="string">&quot;frame_pts:%s frame_pts_time:%s best_effort_ts:%&quot;</span>PRId64<span class="string">&quot; best_effort_ts_time:%s keyframe:%d frame_type:%d time_base:%d/%d\n&quot;</span>,</span><br><span class="line">               ist-&gt;st-&gt;index, av_ts2str(decoded_frame-&gt;pts),</span><br><span class="line">               av_ts2timestr(decoded_frame-&gt;pts, &amp;ist-&gt;st-&gt;time_base),</span><br><span class="line">               best_effort_timestamp,</span><br><span class="line">               av_ts2timestr(best_effort_timestamp, &amp;ist-&gt;st-&gt;time_base),</span><br><span class="line">               decoded_frame-&gt;key_frame, decoded_frame-&gt;pict_type,</span><br><span class="line">               ist-&gt;st-&gt;time_base.num, ist-&gt;st-&gt;time_base.den);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ist-&gt;st-&gt;sample_aspect_ratio.num)</span><br><span class="line">        decoded_frame-&gt;sample_aspect_ratio = ist-&gt;st-&gt;sample_aspect_ratio;</span><br><span class="line">    <span class="comment">// 交给filter处理</span></span><br><span class="line">    err = send_frame_to_filters(ist, decoded_frame);</span><br><span class="line"></span><br><span class="line">fail:</span><br><span class="line">    av_frame_unref(ist-&gt;filter_frame);</span><br><span class="line">    av_frame_unref(decoded_frame);</span><br><span class="line">    <span class="keyword">return</span> err &lt; <span class="number">0</span> ? err : ret;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">send_filter_eof</span><span class="params">(InputStream *ist)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i, ret;</span><br><span class="line">    <span class="comment">/* TODO keep pts also in stream time base to avoid converting back */</span></span><br><span class="line">    <span class="comment">//  由微妙转成AVStream-&gt;time_base</span></span><br><span class="line">    <span class="keyword">int64_t</span> pts = av_rescale_q_rnd(ist-&gt;pts, AV_TIME_BASE_Q, ist-&gt;st-&gt;time_base,</span><br><span class="line">                                   AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; ist-&gt;nb_filters; i++) &#123;</span><br><span class="line">        ret = ifilter_send_eof(ist-&gt;filters[i], pts);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* pkt = NULL means EOF (needed to flush decoder buffers) */</span></span><br><span class="line"><span class="comment">// 处理得到的包，包括区分是视频还是音频包</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">process_input_packet</span><span class="params">(InputStream *ist, <span class="keyword">const</span> AVPacket *pkt, <span class="keyword">int</span> no_eof)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> ret = <span class="number">0</span>, i;</span><br><span class="line">    <span class="keyword">int</span> repeating = <span class="number">0</span>;      <span class="comment">// 修改帧率的时候需要重复？</span></span><br><span class="line">    <span class="keyword">int</span> eof_reached = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    AVPacket avpkt;</span><br><span class="line">    <span class="keyword">if</span> (!ist-&gt;saw_first_ts) &#123;   <span class="comment">// 为了计算下一帧的pts和dts</span></span><br><span class="line">        ist-&gt;dts = ist-&gt;st-&gt;avg_frame_rate.num ? - ist-&gt;dec_ctx-&gt;has_b_frames * AV_TIME_BASE / av_q2d(ist-&gt;st-&gt;avg_frame_rate) : <span class="number">0</span>;</span><br><span class="line">        ist-&gt;pts = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">if</span> (pkt &amp;&amp; pkt-&gt;pts != AV_NOPTS_VALUE &amp;&amp; !ist-&gt;decoding_needed) &#123;</span><br><span class="line">            ist-&gt;dts += av_rescale_q(pkt-&gt;pts, ist-&gt;st-&gt;time_base, AV_TIME_BASE_Q);</span><br><span class="line">            ist-&gt;pts = ist-&gt;dts; <span class="comment">//unused but better to set it to a value thats not totally wrong</span></span><br><span class="line">        &#125;</span><br><span class="line">        ist-&gt;saw_first_ts = <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ist-&gt;next_dts == AV_NOPTS_VALUE)</span><br><span class="line">        ist-&gt;next_dts = ist-&gt;dts;</span><br><span class="line">    <span class="keyword">if</span> (ist-&gt;next_pts == AV_NOPTS_VALUE)</span><br><span class="line">        ist-&gt;next_pts = ist-&gt;pts;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!pkt) &#123;</span><br><span class="line">        <span class="comment">/* EOF handling */</span></span><br><span class="line">        av_init_packet(&amp;avpkt);</span><br><span class="line">        avpkt.data = <span class="literal">NULL</span>;</span><br><span class="line">        avpkt.size = <span class="number">0</span>;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        avpkt = *pkt;       <span class="comment">// 不是EOF时都走该流程</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (pkt &amp;&amp; pkt-&gt;dts != AV_NOPTS_VALUE) &#123;</span><br><span class="line">        ist-&gt;next_dts = ist-&gt;dts = av_rescale_q(pkt-&gt;dts, ist-&gt;st-&gt;time_base, AV_TIME_BASE_Q);</span><br><span class="line">        <span class="keyword">if</span> (ist-&gt;dec_ctx-&gt;codec_type != AVMEDIA_TYPE_VIDEO || !ist-&gt;decoding_needed)</span><br><span class="line">            ist-&gt;next_pts = ist-&gt;pts = ist-&gt;dts;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// while we have more to decode or while the decoder did output something on EOF</span></span><br><span class="line">    <span class="keyword">while</span> (ist-&gt;decoding_needed) &#123;      <span class="comment">// 是否重新解码编码</span></span><br><span class="line">        <span class="keyword">int64_t</span> duration_dts = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int64_t</span> duration_pts = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> got_output = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> decode_failed = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">        ist-&gt;pts = ist-&gt;next_pts;</span><br><span class="line">        ist-&gt;dts = ist-&gt;next_dts;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">switch</span> (ist-&gt;dec_ctx-&gt;codec_type) &#123;</span><br><span class="line">        <span class="keyword">case</span> AVMEDIA_TYPE_AUDIO:</span><br><span class="line">            ret = decode_audio    (ist, repeating ? <span class="literal">NULL</span> : &amp;avpkt, &amp;got_output,</span><br><span class="line">                                   &amp;decode_failed);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> AVMEDIA_TYPE_VIDEO:</span><br><span class="line">            ret = decode_video    (ist, repeating ? <span class="literal">NULL</span> : &amp;avpkt, &amp;got_output, &amp;duration_pts, !pkt,</span><br><span class="line">                                   &amp;decode_failed);</span><br><span class="line">            <span class="keyword">if</span> (!repeating || !pkt || got_output) &#123;</span><br><span class="line">                <span class="keyword">if</span> (pkt &amp;&amp; pkt-&gt;duration) &#123;</span><br><span class="line">                    duration_dts = av_rescale_q(pkt-&gt;duration, ist-&gt;st-&gt;time_base, AV_TIME_BASE_Q);</span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span>(ist-&gt;dec_ctx-&gt;framerate.num != <span class="number">0</span> &amp;&amp; ist-&gt;dec_ctx-&gt;framerate.den != <span class="number">0</span>) &#123;</span><br><span class="line">                    <span class="keyword">int</span> ticks= av_stream_get_parser(ist-&gt;st) ? av_stream_get_parser(ist-&gt;st)-&gt;repeat_pict+<span class="number">1</span> : ist-&gt;dec_ctx-&gt;ticks_per_frame;</span><br><span class="line">                    duration_dts = ((<span class="keyword">int64_t</span>)AV_TIME_BASE *</span><br><span class="line">                                    ist-&gt;dec_ctx-&gt;framerate.den * ticks) /</span><br><span class="line">                                    ist-&gt;dec_ctx-&gt;framerate.num / ist-&gt;dec_ctx-&gt;ticks_per_frame;</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                <span class="keyword">if</span>(ist-&gt;dts != AV_NOPTS_VALUE &amp;&amp; duration_dts) &#123;</span><br><span class="line">                    ist-&gt;next_dts += duration_dts;</span><br><span class="line">                &#125;<span class="keyword">else</span></span><br><span class="line">                    ist-&gt;next_dts = AV_NOPTS_VALUE;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (got_output) &#123;</span><br><span class="line">                <span class="keyword">if</span> (duration_pts &gt; <span class="number">0</span>) &#123;</span><br><span class="line">                    ist-&gt;next_pts += av_rescale_q(duration_pts, ist-&gt;st-&gt;time_base, AV_TIME_BASE_Q);</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    ist-&gt;next_pts += duration_dts;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">default</span>:</span><br><span class="line">            <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ret == AVERROR_EOF) &#123;</span><br><span class="line">            eof_reached = <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (decode_failed) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;Error while decoding stream #%d:%d: %s\n&quot;</span>,</span><br><span class="line">                       ist-&gt;file_index, ist-&gt;st-&gt;index, av_err2str(ret));</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_FATAL, <span class="string">&quot;Error while processing the decoded &quot;</span></span><br><span class="line">                       <span class="string">&quot;data for stream #%d:%d\n&quot;</span>, ist-&gt;file_index, ist-&gt;st-&gt;index);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (!decode_failed || exit_on_error)</span><br><span class="line">                exit_program(<span class="number">1</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (got_output)</span><br><span class="line">            ist-&gt;got_output = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!got_output)</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// During draining, we might get multiple output frames in this loop.</span></span><br><span class="line">        <span class="comment">// ffmpeg.c does not drain the filter chain on configuration changes,</span></span><br><span class="line">        <span class="comment">// which means if we send multiple frames at once to the filters, and</span></span><br><span class="line">        <span class="comment">// one of those frames changes configuration, the buffered frames will</span></span><br><span class="line">        <span class="comment">// be lost. This can upset certain FATE tests.</span></span><br><span class="line">        <span class="comment">// Decode only 1 frame per call on EOF to appease these FATE tests.</span></span><br><span class="line">        <span class="comment">// The ideal solution would be to rewrite decoding to use the new</span></span><br><span class="line">        <span class="comment">// decoding API in a better way.</span></span><br><span class="line">        <span class="keyword">if</span> (!pkt)</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">        repeating = <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* after flushing, send an EOF on all the filter inputs attached to the stream */</span></span><br><span class="line">    <span class="comment">/* except when looping we need to flush but not to send an EOF */</span></span><br><span class="line">    <span class="keyword">if</span> (!pkt &amp;&amp; ist-&gt;decoding_needed &amp;&amp; eof_reached &amp;&amp; !no_eof) &#123;</span><br><span class="line">        <span class="keyword">int</span> ret = send_filter_eof(ist);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_FATAL, <span class="string">&quot;Error marking filters as finished\n&quot;</span>);</span><br><span class="line">            exit_program(<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* handle stream copy */</span></span><br><span class="line">    <span class="keyword">if</span> (!ist-&gt;decoding_needed &amp;&amp; pkt) &#123;</span><br><span class="line">        ist-&gt;dts = ist-&gt;next_dts;</span><br><span class="line">        <span class="keyword">switch</span> (ist-&gt;dec_ctx-&gt;codec_type) &#123;</span><br><span class="line">        <span class="keyword">case</span> AVMEDIA_TYPE_AUDIO:</span><br><span class="line">            av_assert1(pkt-&gt;duration &gt;= <span class="number">0</span>);</span><br><span class="line">            <span class="keyword">if</span> (ist-&gt;dec_ctx-&gt;sample_rate) &#123;</span><br><span class="line">                ist-&gt;next_dts += ((<span class="keyword">int64_t</span>)AV_TIME_BASE * ist-&gt;dec_ctx-&gt;frame_size) /</span><br><span class="line">                                  ist-&gt;dec_ctx-&gt;sample_rate;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                ist-&gt;next_dts += av_rescale_q(pkt-&gt;duration, ist-&gt;st-&gt;time_base, AV_TIME_BASE_Q);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> AVMEDIA_TYPE_VIDEO:</span><br><span class="line">            <span class="keyword">if</span> (ist-&gt;framerate.num) &#123;</span><br><span class="line">                <span class="comment">// <span class="doctag">TODO:</span> Remove work-around for c99-to-c89 issue 7</span></span><br><span class="line">                AVRational time_base_q = AV_TIME_BASE_Q;</span><br><span class="line">                <span class="keyword">int64_t</span> next_dts = av_rescale_q(ist-&gt;next_dts, time_base_q, av_inv_q(ist-&gt;framerate));</span><br><span class="line">                ist-&gt;next_dts = av_rescale_q(next_dts + <span class="number">1</span>, av_inv_q(ist-&gt;framerate), time_base_q);</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (pkt-&gt;duration) &#123;</span><br><span class="line">                <span class="comment">// next_dts 单位为微妙，属于ffmpeg.c程序的处理</span></span><br><span class="line">                ist-&gt;next_dts += av_rescale_q(pkt-&gt;duration, ist-&gt;st-&gt;time_base, AV_TIME_BASE_Q);</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span>(ist-&gt;dec_ctx-&gt;framerate.num != <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="keyword">int</span> ticks= av_stream_get_parser(ist-&gt;st) ? av_stream_get_parser(ist-&gt;st)-&gt;repeat_pict + <span class="number">1</span> : ist-&gt;dec_ctx-&gt;ticks_per_frame;</span><br><span class="line">                ist-&gt;next_dts += ((<span class="keyword">int64_t</span>)AV_TIME_BASE *</span><br><span class="line">                                  ist-&gt;dec_ctx-&gt;framerate.den * ticks) /</span><br><span class="line">                                  ist-&gt;dec_ctx-&gt;framerate.num / ist-&gt;dec_ctx-&gt;ticks_per_frame;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        ist-&gt;pts = ist-&gt;dts;</span><br><span class="line">        ist-&gt;next_pts = ist-&gt;next_dts;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_streams; i++) &#123;</span><br><span class="line">        OutputStream *ost = output_streams[i];</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!check_output_constraints(ist, ost) || ost-&gt;encoding_needed)</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line"></span><br><span class="line">        do_streamcopy(ist, ost, pkt);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> !eof_reached;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">print_sdp</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">char</span> sdp[<span class="number">16384</span>];</span><br><span class="line">    <span class="keyword">int</span> i;</span><br><span class="line">    <span class="keyword">int</span> j;</span><br><span class="line">    AVIOContext *sdp_pb;</span><br><span class="line">    AVFormatContext **avc;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_files; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!output_files[i]-&gt;header_written)</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    avc = av_malloc_array(nb_output_files, <span class="keyword">sizeof</span>(*avc));</span><br><span class="line">    <span class="keyword">if</span> (!avc)</span><br><span class="line">        exit_program(<span class="number">1</span>);</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>, j = <span class="number">0</span>; i &lt; nb_output_files; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!<span class="built_in">strcmp</span>(output_files[i]-&gt;ctx-&gt;oformat-&gt;name, <span class="string">&quot;rtp&quot;</span>)) &#123;</span><br><span class="line">            avc[j] = output_files[i]-&gt;ctx;</span><br><span class="line">            j++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!j)</span><br><span class="line">        <span class="keyword">goto</span> fail;</span><br><span class="line"></span><br><span class="line">    av_sdp_create(avc, j, sdp, <span class="keyword">sizeof</span>(sdp));</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!sdp_filename) &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;SDP:\n%s\n&quot;</span>, sdp);</span><br><span class="line">        fflush(<span class="built_in">stdout</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (avio_open2(&amp;sdp_pb, sdp_filename, AVIO_FLAG_WRITE, &amp;int_cb, <span class="literal">NULL</span>) &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;Failed to open sdp file &#x27;%s&#x27;\n&quot;</span>, sdp_filename);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            avio_printf(sdp_pb, <span class="string">&quot;SDP:\n%s&quot;</span>, sdp);</span><br><span class="line">            avio_closep(&amp;sdp_pb);</span><br><span class="line">            av_freep(&amp;sdp_filename);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">fail:</span><br><span class="line">    av_freep(&amp;avc);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">enum</span> AVPixelFormat <span class="title">get_format</span><span class="params">(AVCodecContext *s, <span class="keyword">const</span> <span class="keyword">enum</span> AVPixelFormat *pix_fmts)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    InputStream *ist = s-&gt;opaque;</span><br><span class="line">    <span class="keyword">const</span> <span class="class"><span class="keyword">enum</span> <span class="title">AVPixelFormat</span> *<span class="title">p</span>;</span></span><br><span class="line">    <span class="keyword">int</span> ret;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) &#123;</span><br><span class="line">        <span class="keyword">const</span> AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p);</span><br><span class="line">        <span class="keyword">const</span> AVCodecHWConfig  *config = <span class="literal">NULL</span>;</span><br><span class="line">        <span class="keyword">int</span> i;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!(desc-&gt;flags &amp; AV_PIX_FMT_FLAG_HWACCEL))</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ist-&gt;hwaccel_id == HWACCEL_GENERIC ||</span><br><span class="line">            ist-&gt;hwaccel_id == HWACCEL_AUTO) &#123;</span><br><span class="line">            <span class="keyword">for</span> (i = <span class="number">0</span>;; i++) &#123;</span><br><span class="line">                config = avcodec_get_hw_config(s-&gt;codec, i);</span><br><span class="line">                <span class="keyword">if</span> (!config)</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                <span class="keyword">if</span> (!(config-&gt;methods &amp;</span><br><span class="line">                      AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX))</span><br><span class="line">                    <span class="keyword">continue</span>;</span><br><span class="line">                <span class="keyword">if</span> (config-&gt;pix_fmt == *p)</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (config) &#123;</span><br><span class="line">            <span class="keyword">if</span> (config-&gt;device_type != ist-&gt;hwaccel_device_type) &#123;</span><br><span class="line">                <span class="comment">// Different hwaccel offered, ignore.</span></span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            ret = hwaccel_decode_init(s);</span><br><span class="line">            <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="keyword">if</span> (ist-&gt;hwaccel_id == HWACCEL_GENERIC) &#123;</span><br><span class="line">                    av_log(<span class="literal">NULL</span>, AV_LOG_FATAL,</span><br><span class="line">                           <span class="string">&quot;%s hwaccel requested for input stream #%d:%d, &quot;</span></span><br><span class="line">                           <span class="string">&quot;but cannot be initialized.\n&quot;</span>,</span><br><span class="line">                           av_hwdevice_get_type_name(config-&gt;device_type),</span><br><span class="line">                           ist-&gt;file_index, ist-&gt;st-&gt;index);</span><br><span class="line">                    <span class="keyword">return</span> AV_PIX_FMT_NONE;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">const</span> HWAccel *hwaccel = <span class="literal">NULL</span>;</span><br><span class="line">            <span class="keyword">int</span> i;</span><br><span class="line">            <span class="keyword">for</span> (i = <span class="number">0</span>; hwaccels[i].name; i++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (hwaccels[i].pix_fmt == *p) &#123;</span><br><span class="line">                    hwaccel = &amp;hwaccels[i];</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (!hwaccel) &#123;</span><br><span class="line">                <span class="comment">// No hwaccel supporting this pixfmt.</span></span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (hwaccel-&gt;id != ist-&gt;hwaccel_id) &#123;</span><br><span class="line">                <span class="comment">// Does not match requested hwaccel.</span></span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            ret = hwaccel-&gt;init(s);</span><br><span class="line">            <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_FATAL,</span><br><span class="line">                       <span class="string">&quot;%s hwaccel requested for input stream #%d:%d, &quot;</span></span><br><span class="line">                       <span class="string">&quot;but cannot be initialized.\n&quot;</span>, hwaccel-&gt;name,</span><br><span class="line">                       ist-&gt;file_index, ist-&gt;st-&gt;index);</span><br><span class="line">                <span class="keyword">return</span> AV_PIX_FMT_NONE;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ist-&gt;hw_frames_ctx) &#123;</span><br><span class="line">            s-&gt;hw_frames_ctx = av_buffer_ref(ist-&gt;hw_frames_ctx);</span><br><span class="line">            <span class="keyword">if</span> (!s-&gt;hw_frames_ctx)</span><br><span class="line">                <span class="keyword">return</span> AV_PIX_FMT_NONE;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        ist-&gt;hwaccel_pix_fmt = *p;</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> *p;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">get_buffer</span><span class="params">(AVCodecContext *s, AVFrame *frame, <span class="keyword">int</span> flags)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    InputStream *ist = s-&gt;opaque;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ist-&gt;hwaccel_get_buffer &amp;&amp; frame-&gt;format == ist-&gt;hwaccel_pix_fmt)</span><br><span class="line">        <span class="keyword">return</span> ist-&gt;hwaccel_get_buffer(s, frame, flags);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> avcodec_default_get_buffer2(s, frame, flags);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 初始化输入流，最主要的就是初始化解码器</span></span><br><span class="line"><span class="comment">// 该流需要重新编码的时候才打开解码器，每个流都是独立的</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">init_input_stream</span><span class="params">(<span class="keyword">int</span> ist_index, <span class="keyword">char</span> *error, <span class="keyword">int</span> error_len)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> ret;</span><br><span class="line">    InputStream *ist = input_streams[ist_index];        <span class="comment">// 获取对应的流</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ist-&gt;decoding_needed) &#123; <span class="comment">// 是否需要解码</span></span><br><span class="line">        AVCodec *codec = ist-&gt;dec;  <span class="comment">// 对应的解码器</span></span><br><span class="line">        <span class="keyword">if</span> (!codec) &#123;               <span class="comment">// 如果没有找到对应的解码器则报错退出</span></span><br><span class="line">            <span class="built_in">snprintf</span>(error, error_len, <span class="string">&quot;Decoder (codec %s) not found for input stream #%d:%d&quot;</span>,</span><br><span class="line">                    avcodec_get_name(ist-&gt;dec_ctx-&gt;codec_id), ist-&gt;file_index, ist-&gt;st-&gt;index);</span><br><span class="line">            <span class="keyword">return</span> AVERROR(EINVAL);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        ist-&gt;dec_ctx-&gt;opaque                = ist;  <span class="comment">// 用户自定义数据</span></span><br><span class="line">        ist-&gt;dec_ctx-&gt;get_format            = get_format;   <span class="comment">//自定义的获取像素格式支持，主要是考虑了硬件加速的场景</span></span><br><span class="line">        ist-&gt;dec_ctx-&gt;get_buffer2           = get_buffer;   <span class="comment">// 自定义的获取buffer ，主要是考虑了硬件加速的场景</span></span><br><span class="line">        ist-&gt;dec_ctx-&gt;thread_safe_callbacks = <span class="number">1</span>;    <span class="comment">// 是否支持多线程操作 get_buffer</span></span><br><span class="line"></span><br><span class="line">        av_opt_set_int(ist-&gt;dec_ctx, <span class="string">&quot;refcounted_frames&quot;</span>, <span class="number">1</span>, <span class="number">0</span>);    <span class="comment">// 解码后的frame由调用者去释放数据</span></span><br><span class="line">        <span class="keyword">if</span> (ist-&gt;dec_ctx-&gt;codec_id == AV_CODEC_ID_DVB_SUBTITLE &amp;&amp;</span><br><span class="line">           (ist-&gt;decoding_needed &amp; DECODING_FOR_OST)) &#123;     <span class="comment">// 如果是字幕操作</span></span><br><span class="line">            av_dict_set(&amp;ist-&gt;decoder_opts, <span class="string">&quot;compute_edt&quot;</span>, <span class="string">&quot;1&quot;</span>, AV_DICT_DONT_OVERWRITE);</span><br><span class="line">            <span class="keyword">if</span> (ist-&gt;decoding_needed &amp; DECODING_FOR_FILTER)</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_WARNING, <span class="string">&quot;Warning using DVB subtitles for filtering and output at the same time is not fully supported, also see -compute_edt [0|1]\n&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        av_dict_set(&amp;ist-&gt;decoder_opts, <span class="string">&quot;sub_text_format&quot;</span>, <span class="string">&quot;ass&quot;</span>, AV_DICT_DONT_OVERWRITE); <span class="comment">// 字幕相关</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/* Useful for subtitles retiming by lavf (FIXME), skipping samples in</span></span><br><span class="line"><span class="comment">         * audio, and video decoders such as cuvid or mediacodec */</span></span><br><span class="line">        ist-&gt;dec_ctx-&gt;pkt_timebase = ist-&gt;st-&gt;time_base;    <span class="comment">// 设置timebase 从AVStream</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!av_dict_get(ist-&gt;decoder_opts, <span class="string">&quot;threads&quot;</span>, <span class="literal">NULL</span>, <span class="number">0</span>))</span><br><span class="line">            av_dict_set(&amp;ist-&gt;decoder_opts, <span class="string">&quot;threads&quot;</span>, <span class="string">&quot;auto&quot;</span>, <span class="number">0</span>);  <span class="comment">//</span></span><br><span class="line">        <span class="comment">/* Attached pics are sparse, therefore we would not want to delay their decoding till EOF. */</span></span><br><span class="line">        <span class="keyword">if</span> (ist-&gt;st-&gt;disposition &amp; AV_DISPOSITION_ATTACHED_PIC)</span><br><span class="line">            av_dict_set(&amp;ist-&gt;decoder_opts, <span class="string">&quot;threads&quot;</span>, <span class="string">&quot;1&quot;</span>, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">        ret = hw_device_setup_for_decode(ist);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="built_in">snprintf</span>(error, error_len, <span class="string">&quot;Device setup failed for &quot;</span></span><br><span class="line">                     <span class="string">&quot;decoder on input stream #%d:%d : %s&quot;</span>,</span><br><span class="line">                     ist-&gt;file_index, ist-&gt;st-&gt;index, av_err2str(ret));</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 打开解码器</span></span><br><span class="line">        <span class="keyword">if</span> ((ret = avcodec_open2(ist-&gt;dec_ctx, codec, &amp;ist-&gt;decoder_opts)) &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (ret == AVERROR_EXPERIMENTAL)</span><br><span class="line">                abort_codec_experimental(codec, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">            <span class="built_in">snprintf</span>(error, error_len,</span><br><span class="line">                     <span class="string">&quot;Error while opening decoder for input stream &quot;</span></span><br><span class="line">                     <span class="string">&quot;#%d:%d : %s&quot;</span>,</span><br><span class="line">                     ist-&gt;file_index, ist-&gt;st-&gt;index, av_err2str(ret));</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line">        &#125;</span><br><span class="line">        assert_avoptions(ist-&gt;decoder_opts);</span><br><span class="line">    &#125;   <span class="comment">// 如果不需要重新编码，则不需要打开解码器</span></span><br><span class="line"></span><br><span class="line">    ist-&gt;next_pts = AV_NOPTS_VALUE;</span><br><span class="line">    ist-&gt;next_dts = AV_NOPTS_VALUE;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> InputStream *<span class="title">get_input_stream</span><span class="params">(OutputStream *ost)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (ost-&gt;source_index &gt;= <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">return</span> input_streams[ost-&gt;source_index];    <span class="comment">// 根据输入源找到对应input_stream</span></span><br><span class="line">    <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">compare_int64</span><span class="params">(<span class="keyword">const</span> <span class="keyword">void</span> *a, <span class="keyword">const</span> <span class="keyword">void</span> *b)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> FFDIFFSIGN(*(<span class="keyword">const</span> <span class="keyword">int64_t</span> *)a, *(<span class="keyword">const</span> <span class="keyword">int64_t</span> *)b);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* open the muxer when all the streams are initialized */</span></span><br><span class="line"><span class="comment">//所有流都初始化完毕再写入头部，所以当对应outputFile还有stream没有初始化万时先存储到muxing_queue</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">check_init_output_file</span><span class="params">(OutputFile *of, <span class="keyword">int</span> file_index)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> ret, i;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; of-&gt;ctx-&gt;nb_streams; i++) &#123;</span><br><span class="line">        OutputStream *ost = output_streams[of-&gt;ost_index + i];</span><br><span class="line">        <span class="keyword">if</span> (!ost-&gt;initialized)</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    of-&gt;ctx-&gt;interrupt_callback = int_cb;</span><br><span class="line">    <span class="comment">// 初始化写入头部</span></span><br><span class="line">    ret = avformat_write_header(of-&gt;ctx, &amp;of-&gt;opts);</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_ERROR,</span><br><span class="line">               <span class="string">&quot;Could not write header for output file #%d &quot;</span></span><br><span class="line">               <span class="string">&quot;(incorrect codec parameters ?): %s\n&quot;</span>,</span><br><span class="line">               file_index, av_err2str(ret));</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//assert_avoptions(of-&gt;opts);</span></span><br><span class="line">    of-&gt;header_written = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">    av_dump_format(of-&gt;ctx, file_index, of-&gt;ctx-&gt;url, <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (sdp_filename || want_sdp)</span><br><span class="line">        print_sdp();</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* flush the muxing queues */</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; of-&gt;ctx-&gt;nb_streams; i++) &#123;</span><br><span class="line">        OutputStream *ost = output_streams[of-&gt;ost_index + i];</span><br><span class="line"></span><br><span class="line">        <span class="comment">/* try to improve muxing time_base (only possible if nothing has been written yet) */</span></span><br><span class="line">        <span class="keyword">if</span> (!av_fifo_size(ost-&gt;muxing_queue))</span><br><span class="line">            ost-&gt;mux_timebase = ost-&gt;st-&gt;time_base; <span class="comment">// 改进time_base</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span> (av_fifo_size(ost-&gt;muxing_queue)) &#123;   <span class="comment">// 队列</span></span><br><span class="line">            AVPacket pkt;</span><br><span class="line">            av_fifo_generic_read(ost-&gt;muxing_queue, &amp;pkt, <span class="keyword">sizeof</span>(pkt), <span class="literal">NULL</span>);</span><br><span class="line">            write_packet(of, &amp;pkt, ost, <span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">init_output_bsfs</span><span class="params">(OutputStream *ost)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    AVBSFContext *ctx;</span><br><span class="line">    <span class="keyword">int</span> i, ret;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!ost-&gt;nb_bitstream_filters)</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; ost-&gt;nb_bitstream_filters; i++) &#123;</span><br><span class="line">        ctx = ost-&gt;bsf_ctx[i];</span><br><span class="line"></span><br><span class="line">        ret = avcodec_parameters_copy(ctx-&gt;par_in,</span><br><span class="line">                                      i ? ost-&gt;bsf_ctx[i - <span class="number">1</span>]-&gt;par_out : ost-&gt;st-&gt;codecpar);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line"></span><br><span class="line">        ctx-&gt;time_base_in = i ? ost-&gt;bsf_ctx[i - <span class="number">1</span>]-&gt;time_base_out : ost-&gt;st-&gt;time_base;</span><br><span class="line"></span><br><span class="line">        ret = av_bsf_init(ctx);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;Error initializing bitstream filter: %s\n&quot;</span>,</span><br><span class="line">                   ost-&gt;bsf_ctx[i]-&gt;filter-&gt;name);</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    ctx = ost-&gt;bsf_ctx[ost-&gt;nb_bitstream_filters - <span class="number">1</span>];</span><br><span class="line">    ret = avcodec_parameters_copy(ost-&gt;st-&gt;codecpar, ctx-&gt;par_out);</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line"></span><br><span class="line">    ost-&gt;st-&gt;time_base = ctx-&gt;time_base_out;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">init_output_stream_streamcopy</span><span class="params">(OutputStream *ost)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    OutputFile *of = output_files[ost-&gt;file_index];</span><br><span class="line">    InputStream *ist = get_input_stream(ost);</span><br><span class="line">    AVCodecParameters *par_dst = ost-&gt;st-&gt;codecpar;</span><br><span class="line">    AVCodecParameters *par_src = ost-&gt;ref_par;</span><br><span class="line">    AVRational sar;</span><br><span class="line">    <span class="keyword">int</span> i, ret;</span><br><span class="line">    <span class="keyword">uint32_t</span> codec_tag = par_dst-&gt;codec_tag;</span><br><span class="line"></span><br><span class="line">    av_assert0(ist &amp;&amp; !ost-&gt;filter);</span><br><span class="line"></span><br><span class="line">    ret = avcodec_parameters_to_context(ost-&gt;enc_ctx, ist-&gt;st-&gt;codecpar);</span><br><span class="line">    <span class="keyword">if</span> (ret &gt;= <span class="number">0</span>)</span><br><span class="line">        ret = av_opt_set_dict(ost-&gt;enc_ctx, &amp;ost-&gt;encoder_opts);</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_FATAL,</span><br><span class="line">               <span class="string">&quot;Error setting up codec context options.\n&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    ret = avcodec_parameters_from_context(par_src, ost-&gt;enc_ctx);</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_FATAL,</span><br><span class="line">               <span class="string">&quot;Error getting reference codec parameters.\n&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!codec_tag) &#123;</span><br><span class="line">        <span class="keyword">unsigned</span> <span class="keyword">int</span> codec_tag_tmp;</span><br><span class="line">        <span class="keyword">if</span> (!of-&gt;ctx-&gt;oformat-&gt;codec_tag ||</span><br><span class="line">            av_codec_get_id (of-&gt;ctx-&gt;oformat-&gt;codec_tag, par_src-&gt;codec_tag) == par_src-&gt;codec_id ||</span><br><span class="line">            !av_codec_get_tag2(of-&gt;ctx-&gt;oformat-&gt;codec_tag, par_src-&gt;codec_id, &amp;codec_tag_tmp))</span><br><span class="line">            codec_tag = par_src-&gt;codec_tag;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    ret = avcodec_parameters_copy(par_dst, par_src);</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line"></span><br><span class="line">    par_dst-&gt;codec_tag = codec_tag;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!ost-&gt;frame_rate.num)</span><br><span class="line">        ost-&gt;frame_rate = ist-&gt;framerate;</span><br><span class="line">    ost-&gt;st-&gt;avg_frame_rate = ost-&gt;frame_rate;</span><br><span class="line"></span><br><span class="line">    ret = avformat_transfer_internal_stream_timing_info(of-&gt;ctx-&gt;oformat, ost-&gt;st, ist-&gt;st, copy_tb);</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// copy timebase while removing common factors</span></span><br><span class="line">    <span class="keyword">if</span> (ost-&gt;st-&gt;time_base.num &lt;= <span class="number">0</span> || ost-&gt;st-&gt;time_base.den &lt;= <span class="number">0</span>)</span><br><span class="line">        ost-&gt;st-&gt;time_base = av_add_q(av_stream_get_codec_timebase(ost-&gt;st), (AVRational)&#123;<span class="number">0</span>, <span class="number">1</span>&#125;);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// copy estimated duration as a hint to the muxer</span></span><br><span class="line">    <span class="keyword">if</span> (ost-&gt;st-&gt;duration &lt;= <span class="number">0</span> &amp;&amp; ist-&gt;st-&gt;duration &gt; <span class="number">0</span>)</span><br><span class="line">        ost-&gt;st-&gt;duration = av_rescale_q(ist-&gt;st-&gt;duration, ist-&gt;st-&gt;time_base, ost-&gt;st-&gt;time_base);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// copy disposition</span></span><br><span class="line">    ost-&gt;st-&gt;disposition = ist-&gt;st-&gt;disposition;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ist-&gt;st-&gt;nb_side_data) &#123;</span><br><span class="line">        <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; ist-&gt;st-&gt;nb_side_data; i++) &#123;</span><br><span class="line">            <span class="keyword">const</span> AVPacketSideData *sd_src = &amp;ist-&gt;st-&gt;side_data[i];</span><br><span class="line">            <span class="keyword">uint8_t</span> *dst_data;</span><br><span class="line"></span><br><span class="line">            dst_data = av_stream_new_side_data(ost-&gt;st, sd_src-&gt;type, sd_src-&gt;size);</span><br><span class="line">            <span class="keyword">if</span> (!dst_data)</span><br><span class="line">                <span class="keyword">return</span> AVERROR(ENOMEM);</span><br><span class="line">            <span class="built_in">memcpy</span>(dst_data, sd_src-&gt;data, sd_src-&gt;size);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ost-&gt;rotate_overridden) &#123;</span><br><span class="line">        <span class="keyword">uint8_t</span> *sd = av_stream_new_side_data(ost-&gt;st, AV_PKT_DATA_DISPLAYMATRIX,</span><br><span class="line">                                              <span class="keyword">sizeof</span>(<span class="keyword">int32_t</span>) * <span class="number">9</span>);</span><br><span class="line">        <span class="keyword">if</span> (sd)</span><br><span class="line">            av_display_rotation_set((<span class="keyword">int32_t</span> *)sd, -ost-&gt;rotate_override_value);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">switch</span> (par_dst-&gt;codec_type) &#123;</span><br><span class="line">    <span class="keyword">case</span> AVMEDIA_TYPE_AUDIO:</span><br><span class="line">        <span class="keyword">if</span> (audio_volume != <span class="number">256</span>) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_FATAL, <span class="string">&quot;-acodec copy and -vol are incompatible (frames are not decoded)\n&quot;</span>);</span><br><span class="line">            exit_program(<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>((par_dst-&gt;block_align == <span class="number">1</span> || par_dst-&gt;block_align == <span class="number">1152</span> || par_dst-&gt;block_align == <span class="number">576</span>) &amp;&amp; par_dst-&gt;codec_id == AV_CODEC_ID_MP3)</span><br><span class="line">            par_dst-&gt;block_align= <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">if</span>(par_dst-&gt;codec_id == AV_CODEC_ID_AC3)</span><br><span class="line">            par_dst-&gt;block_align= <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> AVMEDIA_TYPE_VIDEO:</span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;frame_aspect_ratio.num) &#123; <span class="comment">// overridden by the -aspect cli option</span></span><br><span class="line">            sar =</span><br><span class="line">                av_mul_q(ost-&gt;frame_aspect_ratio,</span><br><span class="line">                         (AVRational)&#123; par_dst-&gt;height, par_dst-&gt;width &#125;);</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_WARNING, <span class="string">&quot;Overriding aspect ratio &quot;</span></span><br><span class="line">                   <span class="string">&quot;with stream copy may produce invalid files\n&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        <span class="keyword">else</span> <span class="keyword">if</span> (ist-&gt;st-&gt;sample_aspect_ratio.num)</span><br><span class="line">            sar = ist-&gt;st-&gt;sample_aspect_ratio;</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">            sar = par_src-&gt;sample_aspect_ratio;</span><br><span class="line">        ost-&gt;st-&gt;sample_aspect_ratio = par_dst-&gt;sample_aspect_ratio = sar;</span><br><span class="line">        ost-&gt;st-&gt;avg_frame_rate = ist-&gt;st-&gt;avg_frame_rate;</span><br><span class="line">        ost-&gt;st-&gt;r_frame_rate = ist-&gt;st-&gt;r_frame_rate;</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    ost-&gt;mux_timebase = ist-&gt;st-&gt;time_base;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">set_encoder_id</span><span class="params">(OutputFile *of, OutputStream *ost)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    AVDictionaryEntry *e;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">uint8_t</span> *encoder_string;</span><br><span class="line">    <span class="keyword">int</span> encoder_string_len;</span><br><span class="line">    <span class="keyword">int</span> format_flags = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> codec_flags = ost-&gt;enc_ctx-&gt;flags;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (av_dict_get(ost-&gt;st-&gt;metadata, <span class="string">&quot;encoder&quot;</span>,  <span class="literal">NULL</span>, <span class="number">0</span>))</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">    e = av_dict_get(of-&gt;opts, <span class="string">&quot;fflags&quot;</span>, <span class="literal">NULL</span>, <span class="number">0</span>);</span><br><span class="line">    <span class="keyword">if</span> (e) &#123;</span><br><span class="line">        <span class="keyword">const</span> AVOption *o = av_opt_find(of-&gt;ctx, <span class="string">&quot;fflags&quot;</span>, <span class="literal">NULL</span>, <span class="number">0</span>, <span class="number">0</span>);</span><br><span class="line">        <span class="keyword">if</span> (!o)</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        av_opt_eval_flags(of-&gt;ctx, o, e-&gt;value, &amp;format_flags);</span><br><span class="line">    &#125;</span><br><span class="line">    e = av_dict_get(ost-&gt;encoder_opts, <span class="string">&quot;flags&quot;</span>, <span class="literal">NULL</span>, <span class="number">0</span>);</span><br><span class="line">    <span class="keyword">if</span> (e) &#123;</span><br><span class="line">        <span class="keyword">const</span> AVOption *o = av_opt_find(ost-&gt;enc_ctx, <span class="string">&quot;flags&quot;</span>, <span class="literal">NULL</span>, <span class="number">0</span>, <span class="number">0</span>);</span><br><span class="line">        <span class="keyword">if</span> (!o)</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        av_opt_eval_flags(ost-&gt;enc_ctx, o, e-&gt;value, &amp;codec_flags);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    encoder_string_len = <span class="keyword">sizeof</span>(LIBAVCODEC_IDENT) + <span class="built_in">strlen</span>(ost-&gt;enc-&gt;name) + <span class="number">2</span>;</span><br><span class="line">    encoder_string     = av_mallocz(encoder_string_len);</span><br><span class="line">    <span class="keyword">if</span> (!encoder_string)</span><br><span class="line">        exit_program(<span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!(format_flags &amp; AVFMT_FLAG_BITEXACT) &amp;&amp; !(codec_flags &amp; AV_CODEC_FLAG_BITEXACT))</span><br><span class="line">        av_strlcpy(encoder_string, LIBAVCODEC_IDENT <span class="string">&quot; &quot;</span>, encoder_string_len);</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">        av_strlcpy(encoder_string, <span class="string">&quot;Lavc &quot;</span>, encoder_string_len);</span><br><span class="line">    av_strlcat(encoder_string, ost-&gt;enc-&gt;name, encoder_string_len);</span><br><span class="line">    av_dict_set(&amp;ost-&gt;st-&gt;metadata, <span class="string">&quot;encoder&quot;</span>,  encoder_string,</span><br><span class="line">                AV_DICT_DONT_STRDUP_VAL | AV_DICT_DONT_OVERWRITE);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">parse_forced_key_frames</span><span class="params">(<span class="keyword">char</span> *kf, OutputStream *ost,</span></span></span><br><span class="line"><span class="function"><span class="params">                                    AVCodecContext *avctx)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">char</span> *p;</span><br><span class="line">    <span class="keyword">int</span> n = <span class="number">1</span>, i, size, index = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int64_t</span> t, *pts;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (p = kf; *p; p++)</span><br><span class="line">        <span class="keyword">if</span> (*p == <span class="string">&#x27;,&#x27;</span>)</span><br><span class="line">            n++;</span><br><span class="line">    size = n;</span><br><span class="line">    pts = av_malloc_array(size, <span class="keyword">sizeof</span>(*pts));</span><br><span class="line">    <span class="keyword">if</span> (!pts) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_FATAL, <span class="string">&quot;Could not allocate forced key frames array.\n&quot;</span>);</span><br><span class="line">        exit_program(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    p = kf;</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">        <span class="keyword">char</span> *next = <span class="built_in">strchr</span>(p, <span class="string">&#x27;,&#x27;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (next)</span><br><span class="line">            *next++ = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!<span class="built_in">memcmp</span>(p, <span class="string">&quot;chapters&quot;</span>, <span class="number">8</span>)) &#123;</span><br><span class="line"></span><br><span class="line">            AVFormatContext *avf = output_files[ost-&gt;file_index]-&gt;ctx;</span><br><span class="line">            <span class="keyword">int</span> j;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (avf-&gt;nb_chapters &gt; INT_MAX - size ||</span><br><span class="line">                !(pts = av_realloc_f(pts, size += avf-&gt;nb_chapters - <span class="number">1</span>,</span><br><span class="line">                                     <span class="keyword">sizeof</span>(*pts)))) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_FATAL,</span><br><span class="line">                       <span class="string">&quot;Could not allocate forced key frames array.\n&quot;</span>);</span><br><span class="line">                exit_program(<span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            t = p[<span class="number">8</span>] ? parse_time_or_die(<span class="string">&quot;force_key_frames&quot;</span>, p + <span class="number">8</span>, <span class="number">1</span>) : <span class="number">0</span>;</span><br><span class="line">            t = av_rescale_q(t, AV_TIME_BASE_Q, avctx-&gt;time_base);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; avf-&gt;nb_chapters; j++) &#123;</span><br><span class="line">                AVChapter *c = avf-&gt;chapters[j];</span><br><span class="line">                av_assert1(index &lt; size);</span><br><span class="line">                pts[index++] = av_rescale_q(c-&gt;start, c-&gt;time_base,</span><br><span class="line">                                            avctx-&gt;time_base) + t;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line"></span><br><span class="line">            t = parse_time_or_die(<span class="string">&quot;force_key_frames&quot;</span>, p, <span class="number">1</span>);</span><br><span class="line">            av_assert1(index &lt; size);</span><br><span class="line">            pts[index++] = av_rescale_q(t, AV_TIME_BASE_Q, avctx-&gt;time_base);</span><br><span class="line"></span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        p = next;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    av_assert0(index == size);</span><br><span class="line">    qsort(pts, size, <span class="keyword">sizeof</span>(*pts), compare_int64);</span><br><span class="line">    ost-&gt;forced_kf_count = size;</span><br><span class="line">    ost-&gt;forced_kf_pts   = pts;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @brief 设置编码器time_base</span></span><br><span class="line"><span class="comment"> * @param ost</span></span><br><span class="line"><span class="comment"> * @param default_time_base  视频默认使用帧率，音频默认使用采样率</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">init_encoder_time_base</span><span class="params">(OutputStream *ost, AVRational default_time_base)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    InputStream *ist = get_input_stream(ost);</span><br><span class="line">    AVCodecContext *enc_ctx = ost-&gt;enc_ctx;</span><br><span class="line">    AVFormatContext *oc;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ost-&gt;enc_timebase.num &gt; <span class="number">0</span>) &#123;</span><br><span class="line">        enc_ctx-&gt;time_base = ost-&gt;enc_timebase;     <span class="comment">// 如果设置了输出帧率</span></span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ost-&gt;enc_timebase.num &lt; <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">if</span> (ist) &#123;</span><br><span class="line">            enc_ctx-&gt;time_base = ist-&gt;st-&gt;time_base;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        oc = output_files[ost-&gt;file_index]-&gt;ctx;</span><br><span class="line">        av_log(oc, AV_LOG_WARNING, <span class="string">&quot;Input stream data not available, using default time base\n&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    enc_ctx-&gt;time_base = default_time_base;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">init_output_stream_encode</span><span class="params">(OutputStream *ost)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    InputStream *ist = get_input_stream(ost);</span><br><span class="line">    AVCodecContext *enc_ctx = ost-&gt;enc_ctx;</span><br><span class="line">    AVCodecContext *dec_ctx = <span class="literal">NULL</span>;</span><br><span class="line">    AVFormatContext *oc = output_files[ost-&gt;file_index]-&gt;ctx;</span><br><span class="line">    <span class="keyword">int</span> j, ret;</span><br><span class="line"></span><br><span class="line">    set_encoder_id(output_files[ost-&gt;file_index], ost);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Muxers use AV_PKT_DATA_DISPLAYMATRIX to signal rotation. On the other</span></span><br><span class="line">    <span class="comment">// hand, the legacy API makes demuxers set &quot;rotate&quot; metadata entries,</span></span><br><span class="line">    <span class="comment">// which have to be filtered out to prevent leaking them to output files.</span></span><br><span class="line">    av_dict_set(&amp;ost-&gt;st-&gt;metadata, <span class="string">&quot;rotate&quot;</span>, <span class="literal">NULL</span>, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ist) &#123;</span><br><span class="line">        ost-&gt;st-&gt;disposition          = ist-&gt;st-&gt;disposition;</span><br><span class="line"></span><br><span class="line">        dec_ctx = ist-&gt;dec_ctx;</span><br><span class="line"></span><br><span class="line">        enc_ctx-&gt;chroma_sample_location = dec_ctx-&gt;chroma_sample_location;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; oc-&gt;nb_streams; j++) &#123;</span><br><span class="line">            AVStream *st = oc-&gt;streams[j];</span><br><span class="line">            <span class="keyword">if</span> (st != ost-&gt;st &amp;&amp; st-&gt;codecpar-&gt;codec_type == ost-&gt;st-&gt;codecpar-&gt;codec_type)</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (j == oc-&gt;nb_streams)</span><br><span class="line">            <span class="keyword">if</span> (ost-&gt;st-&gt;codecpar-&gt;codec_type == AVMEDIA_TYPE_AUDIO ||</span><br><span class="line">                ost-&gt;st-&gt;codecpar-&gt;codec_type == AVMEDIA_TYPE_VIDEO)</span><br><span class="line">                ost-&gt;st-&gt;disposition = AV_DISPOSITION_DEFAULT;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (enc_ctx-&gt;codec_type == AVMEDIA_TYPE_VIDEO) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!ost-&gt;frame_rate.num)</span><br><span class="line">            ost-&gt;frame_rate = av_buffersink_get_frame_rate(ost-&gt;filter-&gt;filter);</span><br><span class="line">        <span class="keyword">if</span> (ist &amp;&amp; !ost-&gt;frame_rate.num)</span><br><span class="line">            ost-&gt;frame_rate = ist-&gt;framerate;</span><br><span class="line">        <span class="keyword">if</span> (ist &amp;&amp; !ost-&gt;frame_rate.num)</span><br><span class="line">            ost-&gt;frame_rate = ist-&gt;st-&gt;r_frame_rate;</span><br><span class="line">        <span class="keyword">if</span> (ist &amp;&amp; !ost-&gt;frame_rate.num) &#123;</span><br><span class="line">            ost-&gt;frame_rate = (AVRational)&#123;<span class="number">25</span>, <span class="number">1</span>&#125;;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_WARNING,</span><br><span class="line">                   <span class="string">&quot;No information &quot;</span></span><br><span class="line">                   <span class="string">&quot;about the input framerate is available. Falling &quot;</span></span><br><span class="line">                   <span class="string">&quot;back to a default value of 25fps for output stream #%d:%d. Use the -r option &quot;</span></span><br><span class="line">                   <span class="string">&quot;if you want a different framerate.\n&quot;</span>,</span><br><span class="line">                   ost-&gt;file_index, ost-&gt;index);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;enc-&gt;supported_framerates &amp;&amp; !ost-&gt;force_fps) &#123;</span><br><span class="line">            <span class="keyword">int</span> idx = av_find_nearest_q_idx(ost-&gt;frame_rate, ost-&gt;enc-&gt;supported_framerates);</span><br><span class="line">            ost-&gt;frame_rate = ost-&gt;enc-&gt;supported_framerates[idx];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// reduce frame rate for mpeg4 to be within the spec limits</span></span><br><span class="line">        <span class="keyword">if</span> (enc_ctx-&gt;codec_id == AV_CODEC_ID_MPEG4) &#123;</span><br><span class="line">            av_reduce(&amp;ost-&gt;frame_rate.num, &amp;ost-&gt;frame_rate.den,</span><br><span class="line">                      ost-&gt;frame_rate.num, ost-&gt;frame_rate.den, <span class="number">65535</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">switch</span> (enc_ctx-&gt;codec_type) &#123;</span><br><span class="line">    <span class="keyword">case</span> AVMEDIA_TYPE_AUDIO:</span><br><span class="line">        enc_ctx-&gt;sample_fmt     = av_buffersink_get_format(ost-&gt;filter-&gt;filter);</span><br><span class="line">        <span class="keyword">if</span> (dec_ctx)</span><br><span class="line">            enc_ctx-&gt;bits_per_raw_sample = FFMIN(dec_ctx-&gt;bits_per_raw_sample,</span><br><span class="line">                                                 av_get_bytes_per_sample(enc_ctx-&gt;sample_fmt) &lt;&lt; <span class="number">3</span>);</span><br><span class="line">        enc_ctx-&gt;sample_rate    = av_buffersink_get_sample_rate(ost-&gt;filter-&gt;filter);</span><br><span class="line">        enc_ctx-&gt;channel_layout = av_buffersink_get_channel_layout(ost-&gt;filter-&gt;filter);</span><br><span class="line">        enc_ctx-&gt;channels       = av_buffersink_get_channels(ost-&gt;filter-&gt;filter);</span><br><span class="line"></span><br><span class="line">        init_encoder_time_base(ost, av_make_q(<span class="number">1</span>, enc_ctx-&gt;sample_rate));</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">case</span> AVMEDIA_TYPE_VIDEO:</span><br><span class="line">        <span class="comment">// av_buffersink_get_不管你filtergraph里面做了什么东西，我只管输出的格式还有一些其他参数</span></span><br><span class="line">        init_encoder_time_base(ost, av_inv_q(ost-&gt;frame_rate));     <span class="comment">// 默认使用分析出来的帧率</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!(enc_ctx-&gt;time_base.num &amp;&amp; enc_ctx-&gt;time_base.den))</span><br><span class="line">            enc_ctx-&gt;time_base = av_buffersink_get_time_base(ost-&gt;filter-&gt;filter);</span><br><span class="line">        <span class="keyword">if</span> (   av_q2d(enc_ctx-&gt;time_base) &lt; <span class="number">0.001</span> &amp;&amp; video_sync_method != VSYNC_PASSTHROUGH</span><br><span class="line">           &amp;&amp; (video_sync_method == VSYNC_CFR || video_sync_method == VSYNC_VSCFR || (video_sync_method == VSYNC_AUTO &amp;&amp; !(oc-&gt;oformat-&gt;flags &amp; AVFMT_VARIABLE_FPS))))&#123;</span><br><span class="line">            av_log(oc, AV_LOG_WARNING, <span class="string">&quot;Frame rate very high for a muxer not efficiently supporting it.\n&quot;</span></span><br><span class="line">                                       <span class="string">&quot;Please consider specifying a lower framerate, a different muxer or -vsync 2\n&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; ost-&gt;forced_kf_count; j++)</span><br><span class="line">            ost-&gt;forced_kf_pts[j] = av_rescale_q(ost-&gt;forced_kf_pts[j],</span><br><span class="line">                                                 AV_TIME_BASE_Q,</span><br><span class="line">                                                 enc_ctx-&gt;time_base);</span><br><span class="line"></span><br><span class="line">        enc_ctx-&gt;width  = av_buffersink_get_w(ost-&gt;filter-&gt;filter);</span><br><span class="line">        enc_ctx-&gt;height = av_buffersink_get_h(ost-&gt;filter-&gt;filter);</span><br><span class="line">        enc_ctx-&gt;sample_aspect_ratio = ost-&gt;st-&gt;sample_aspect_ratio =</span><br><span class="line">            ost-&gt;frame_aspect_ratio.num ? <span class="comment">// overridden by the -aspect cli option</span></span><br><span class="line">            av_mul_q(ost-&gt;frame_aspect_ratio, (AVRational)&#123; enc_ctx-&gt;height, enc_ctx-&gt;width &#125;) :</span><br><span class="line">            av_buffersink_get_sample_aspect_ratio(ost-&gt;filter-&gt;filter);</span><br><span class="line"></span><br><span class="line">        enc_ctx-&gt;pix_fmt = av_buffersink_get_format(ost-&gt;filter-&gt;filter);</span><br><span class="line">        <span class="keyword">if</span> (dec_ctx)</span><br><span class="line">            enc_ctx-&gt;bits_per_raw_sample = FFMIN(dec_ctx-&gt;bits_per_raw_sample,</span><br><span class="line">                                                 av_pix_fmt_desc_get(enc_ctx-&gt;pix_fmt)-&gt;comp[<span class="number">0</span>].depth);</span><br><span class="line"></span><br><span class="line">        enc_ctx-&gt;framerate = ost-&gt;frame_rate;</span><br><span class="line"></span><br><span class="line">        ost-&gt;st-&gt;avg_frame_rate = ost-&gt;frame_rate;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!dec_ctx ||</span><br><span class="line">            enc_ctx-&gt;width   != dec_ctx-&gt;width  ||</span><br><span class="line">            enc_ctx-&gt;height  != dec_ctx-&gt;height ||</span><br><span class="line">            enc_ctx-&gt;pix_fmt != dec_ctx-&gt;pix_fmt) &#123;</span><br><span class="line">            enc_ctx-&gt;bits_per_raw_sample = frame_bits_per_raw_sample;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;top_field_first == <span class="number">0</span>) &#123;</span><br><span class="line">            enc_ctx-&gt;field_order = AV_FIELD_BB;</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (ost-&gt;top_field_first == <span class="number">1</span>) &#123;</span><br><span class="line">            enc_ctx-&gt;field_order = AV_FIELD_TT;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;forced_keyframes) &#123;</span><br><span class="line">            <span class="keyword">if</span> (!<span class="built_in">strncmp</span>(ost-&gt;forced_keyframes, <span class="string">&quot;expr:&quot;</span>, <span class="number">5</span>)) &#123;</span><br><span class="line">                ret = av_expr_parse(&amp;ost-&gt;forced_keyframes_pexpr, ost-&gt;forced_keyframes+<span class="number">5</span>,</span><br><span class="line">                                    forced_keyframes_const_names, <span class="literal">NULL</span>, <span class="literal">NULL</span>, <span class="literal">NULL</span>, <span class="literal">NULL</span>, <span class="number">0</span>, <span class="literal">NULL</span>);</span><br><span class="line">                <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                    av_log(<span class="literal">NULL</span>, AV_LOG_ERROR,</span><br><span class="line">                           <span class="string">&quot;Invalid force_key_frames expression &#x27;%s&#x27;\n&quot;</span>, ost-&gt;forced_keyframes+<span class="number">5</span>);</span><br><span class="line">                    <span class="keyword">return</span> ret;</span><br><span class="line">                &#125;</span><br><span class="line">                ost-&gt;forced_keyframes_expr_const_values[FKF_N] = <span class="number">0</span>;</span><br><span class="line">                ost-&gt;forced_keyframes_expr_const_values[FKF_N_FORCED] = <span class="number">0</span>;</span><br><span class="line">                ost-&gt;forced_keyframes_expr_const_values[FKF_PREV_FORCED_N] = NAN;</span><br><span class="line">                ost-&gt;forced_keyframes_expr_const_values[FKF_PREV_FORCED_T] = NAN;</span><br><span class="line"></span><br><span class="line">                <span class="comment">// Don&#x27;t parse the &#x27;forced_keyframes&#x27; in case of &#x27;keep-source-keyframes&#x27;,</span></span><br><span class="line">                <span class="comment">// parse it only for static kf timings</span></span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span>(<span class="built_in">strncmp</span>(ost-&gt;forced_keyframes, <span class="string">&quot;source&quot;</span>, <span class="number">6</span>)) &#123;</span><br><span class="line">                parse_forced_key_frames(ost-&gt;forced_keyframes, ost, ost-&gt;enc_ctx);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> AVMEDIA_TYPE_SUBTITLE:</span><br><span class="line">        enc_ctx-&gt;time_base = AV_TIME_BASE_Q;</span><br><span class="line">        <span class="keyword">if</span> (!enc_ctx-&gt;width) &#123;</span><br><span class="line">            enc_ctx-&gt;width     = input_streams[ost-&gt;source_index]-&gt;st-&gt;codecpar-&gt;width;</span><br><span class="line">            enc_ctx-&gt;height    = input_streams[ost-&gt;source_index]-&gt;st-&gt;codecpar-&gt;height;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> AVMEDIA_TYPE_DATA:</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">default</span>:</span><br><span class="line">        <span class="built_in">abort</span>();</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    ost-&gt;mux_timebase = enc_ctx-&gt;time_base; <span class="comment">// 来自编码器</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 初始化输出stream，主要是初始化编码器</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">init_output_stream</span><span class="params">(OutputStream *ost, <span class="keyword">char</span> *error, <span class="keyword">int</span> error_len)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> ret = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ost-&gt;encoding_needed) &#123; <span class="comment">// 如果需要重新编码</span></span><br><span class="line">        AVCodec      *codec = ost-&gt;enc;</span><br><span class="line">        AVCodecContext *dec = <span class="literal">NULL</span>;</span><br><span class="line">        InputStream *ist;       <span class="comment">// 对应输入stream的编码信息</span></span><br><span class="line"></span><br><span class="line">        ret = init_output_stream_encode(ost);   <span class="comment">//</span></span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> ((ist = get_input_stream(ost)))</span><br><span class="line">            dec = ist-&gt;dec_ctx;</span><br><span class="line">        <span class="keyword">if</span> (dec &amp;&amp; dec-&gt;subtitle_header) &#123;</span><br><span class="line">            <span class="comment">/* ASS code assumes this buffer is null terminated so add extra byte. */</span></span><br><span class="line">            ost-&gt;enc_ctx-&gt;subtitle_header = av_mallocz(dec-&gt;subtitle_header_size + <span class="number">1</span>);</span><br><span class="line">            <span class="keyword">if</span> (!ost-&gt;enc_ctx-&gt;subtitle_header)</span><br><span class="line">                <span class="keyword">return</span> AVERROR(ENOMEM);</span><br><span class="line">            <span class="built_in">memcpy</span>(ost-&gt;enc_ctx-&gt;subtitle_header, dec-&gt;subtitle_header, dec-&gt;subtitle_header_size);</span><br><span class="line">            ost-&gt;enc_ctx-&gt;subtitle_header_size = dec-&gt;subtitle_header_size;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (!av_dict_get(ost-&gt;encoder_opts, <span class="string">&quot;threads&quot;</span>, <span class="literal">NULL</span>, <span class="number">0</span>))</span><br><span class="line">            av_dict_set(&amp;ost-&gt;encoder_opts, <span class="string">&quot;threads&quot;</span>, <span class="string">&quot;auto&quot;</span>, <span class="number">0</span>);</span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;enc-&gt;type == AVMEDIA_TYPE_AUDIO &amp;&amp;</span><br><span class="line">            !codec-&gt;defaults &amp;&amp;</span><br><span class="line">            !av_dict_get(ost-&gt;encoder_opts, <span class="string">&quot;b&quot;</span>, <span class="literal">NULL</span>, <span class="number">0</span>) &amp;&amp;</span><br><span class="line">            !av_dict_get(ost-&gt;encoder_opts, <span class="string">&quot;ab&quot;</span>, <span class="literal">NULL</span>, <span class="number">0</span>))</span><br><span class="line">            av_dict_set(&amp;ost-&gt;encoder_opts, <span class="string">&quot;b&quot;</span>, <span class="string">&quot;128000&quot;</span>, <span class="number">0</span>);<span class="comment">//默认128kbps</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;filter &amp;&amp; av_buffersink_get_hw_frames_ctx(ost-&gt;filter-&gt;filter) &amp;&amp;</span><br><span class="line">            ((AVHWFramesContext*)av_buffersink_get_hw_frames_ctx(ost-&gt;filter-&gt;filter)-&gt;data)-&gt;format ==</span><br><span class="line">            av_buffersink_get_format(ost-&gt;filter-&gt;filter)) &#123;</span><br><span class="line">            ost-&gt;enc_ctx-&gt;hw_frames_ctx = av_buffer_ref(av_buffersink_get_hw_frames_ctx(ost-&gt;filter-&gt;filter));</span><br><span class="line">            <span class="keyword">if</span> (!ost-&gt;enc_ctx-&gt;hw_frames_ctx)</span><br><span class="line">                <span class="keyword">return</span> AVERROR(ENOMEM);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            ret = hw_device_setup_for_encode(ost);</span><br><span class="line">            <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="built_in">snprintf</span>(error, error_len, <span class="string">&quot;Device setup failed for &quot;</span></span><br><span class="line">                         <span class="string">&quot;encoder on output stream #%d:%d : %s&quot;</span>,</span><br><span class="line">                     ost-&gt;file_index, ost-&gt;index, av_err2str(ret));</span><br><span class="line">                <span class="keyword">return</span> ret;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (ist &amp;&amp; ist-&gt;dec-&gt;type == AVMEDIA_TYPE_SUBTITLE &amp;&amp; ost-&gt;enc-&gt;type == AVMEDIA_TYPE_SUBTITLE) &#123;</span><br><span class="line">            <span class="keyword">int</span> input_props = <span class="number">0</span>, output_props = <span class="number">0</span>;</span><br><span class="line">            AVCodecDescriptor <span class="keyword">const</span> *input_descriptor =</span><br><span class="line">                avcodec_descriptor_get(dec-&gt;codec_id);</span><br><span class="line">            AVCodecDescriptor <span class="keyword">const</span> *output_descriptor =</span><br><span class="line">                avcodec_descriptor_get(ost-&gt;enc_ctx-&gt;codec_id);</span><br><span class="line">            <span class="keyword">if</span> (input_descriptor)</span><br><span class="line">                input_props = input_descriptor-&gt;props &amp; (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);</span><br><span class="line">            <span class="keyword">if</span> (output_descriptor)</span><br><span class="line">                output_props = output_descriptor-&gt;props &amp; (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);</span><br><span class="line">            <span class="keyword">if</span> (input_props &amp;&amp; output_props &amp;&amp; input_props != output_props) &#123;</span><br><span class="line">                <span class="built_in">snprintf</span>(error, error_len,</span><br><span class="line">                         <span class="string">&quot;Subtitle encoding currently only possible from text to text &quot;</span></span><br><span class="line">                         <span class="string">&quot;or bitmap to bitmap&quot;</span>);</span><br><span class="line">                <span class="keyword">return</span> AVERROR_INVALIDDATA;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 根据设置的参数打开编码， encoder_opts的信息主要来自命令行的设置</span></span><br><span class="line">        <span class="keyword">if</span> ((ret = avcodec_open2(ost-&gt;enc_ctx, codec, &amp;ost-&gt;encoder_opts)) &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (ret == AVERROR_EXPERIMENTAL)</span><br><span class="line">                abort_codec_experimental(codec, <span class="number">1</span>);</span><br><span class="line">            <span class="built_in">snprintf</span>(error, error_len,</span><br><span class="line">                     <span class="string">&quot;Error while opening encoder for output stream #%d:%d - &quot;</span></span><br><span class="line">                     <span class="string">&quot;maybe incorrect parameters such as bit_rate, rate, width or height&quot;</span>,</span><br><span class="line">                    ost-&gt;file_index, ost-&gt;index);</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;enc-&gt;type == AVMEDIA_TYPE_AUDIO &amp;&amp;</span><br><span class="line">            !(ost-&gt;enc-&gt;capabilities &amp; AV_CODEC_CAP_VARIABLE_FRAME_SIZE))</span><br><span class="line">            av_buffersink_set_frame_size(ost-&gt;filter-&gt;filter,</span><br><span class="line">                                            ost-&gt;enc_ctx-&gt;frame_size);</span><br><span class="line">        assert_avoptions(ost-&gt;encoder_opts);</span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;enc_ctx-&gt;bit_rate &amp;&amp; ost-&gt;enc_ctx-&gt;bit_rate &lt; <span class="number">1000</span> &amp;&amp;</span><br><span class="line">            ost-&gt;enc_ctx-&gt;codec_id != AV_CODEC_ID_CODEC2 <span class="comment">/* don&#x27;t complain about 700 bit/s modes */</span>)</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_WARNING, <span class="string">&quot;The bitrate parameter is set too low.&quot;</span></span><br><span class="line">                                         <span class="string">&quot; It takes bits/s as argument, not kbits/s\n&quot;</span>);</span><br><span class="line">        <span class="comment">// 将编码器的信息拷贝到stream的codecpar，以便写复用的时候使用，拷贝到输出流</span></span><br><span class="line">        ret = avcodec_parameters_from_context(ost-&gt;st-&gt;codecpar, ost-&gt;enc_ctx);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_FATAL,</span><br><span class="line">                   <span class="string">&quot;Error initializing the output stream codec context.\n&quot;</span>);</span><br><span class="line">            exit_program(<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">/*</span></span><br><span class="line"><span class="comment">         * <span class="doctag">FIXME:</span> ost-&gt;st-&gt;codec should&#x27;t be needed here anymore.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        ret = avcodec_copy_context(ost-&gt;st-&gt;codec, ost-&gt;enc_ctx);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;enc_ctx-&gt;nb_coded_side_data) &#123;</span><br><span class="line">            <span class="keyword">int</span> i;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; ost-&gt;enc_ctx-&gt;nb_coded_side_data; i++) &#123;</span><br><span class="line">                <span class="keyword">const</span> AVPacketSideData *sd_src = &amp;ost-&gt;enc_ctx-&gt;coded_side_data[i];</span><br><span class="line">                <span class="keyword">uint8_t</span> *dst_data;</span><br><span class="line"></span><br><span class="line">                dst_data = av_stream_new_side_data(ost-&gt;st, sd_src-&gt;type, sd_src-&gt;size);</span><br><span class="line">                <span class="keyword">if</span> (!dst_data)</span><br><span class="line">                    <span class="keyword">return</span> AVERROR(ENOMEM);</span><br><span class="line">                <span class="built_in">memcpy</span>(dst_data, sd_src-&gt;data, sd_src-&gt;size);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/*</span></span><br><span class="line"><span class="comment">         * Add global input side data. For now this is naive, and copies it</span></span><br><span class="line"><span class="comment">         * from the input stream&#x27;s global side data. All side data should</span></span><br><span class="line"><span class="comment">         * really be funneled over AVFrame and libavfilter, then added back to</span></span><br><span class="line"><span class="comment">         * packet side data, and then potentially using the first packet for</span></span><br><span class="line"><span class="comment">         * global side data.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="keyword">if</span> (ist) &#123;</span><br><span class="line">            <span class="keyword">int</span> i;</span><br><span class="line">            <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; ist-&gt;st-&gt;nb_side_data; i++) &#123;</span><br><span class="line">                AVPacketSideData *sd = &amp;ist-&gt;st-&gt;side_data[i];</span><br><span class="line">                <span class="keyword">uint8_t</span> *dst = av_stream_new_side_data(ost-&gt;st, sd-&gt;type, sd-&gt;size);</span><br><span class="line">                <span class="keyword">if</span> (!dst)</span><br><span class="line">                    <span class="keyword">return</span> AVERROR(ENOMEM);</span><br><span class="line">                <span class="built_in">memcpy</span>(dst, sd-&gt;data, sd-&gt;size);</span><br><span class="line">                <span class="keyword">if</span> (ist-&gt;autorotate &amp;&amp; sd-&gt;type == AV_PKT_DATA_DISPLAYMATRIX)</span><br><span class="line">                    av_display_rotation_set((<span class="keyword">uint32_t</span> *)dst, <span class="number">0</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// copy timebase while removing common factors</span></span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;st-&gt;time_base.num &lt;= <span class="number">0</span> || ost-&gt;st-&gt;time_base.den &lt;= <span class="number">0</span>)</span><br><span class="line">            ost-&gt;st-&gt;time_base = av_add_q(ost-&gt;enc_ctx-&gt;time_base, (AVRational)&#123;<span class="number">0</span>, <span class="number">1</span>&#125;);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// copy estimated duration as a hint to the muxer</span></span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;st-&gt;duration &lt;= <span class="number">0</span> &amp;&amp; ist &amp;&amp; ist-&gt;st-&gt;duration &gt; <span class="number">0</span>)</span><br><span class="line">            ost-&gt;st-&gt;duration = av_rescale_q(ist-&gt;st-&gt;duration, ist-&gt;st-&gt;time_base, ost-&gt;st-&gt;time_base);</span><br><span class="line"></span><br><span class="line">        ost-&gt;st-&gt;codec-&gt;codec= ost-&gt;enc_ctx-&gt;codec;</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (ost-&gt;stream_copy) &#123;</span><br><span class="line">        ret = init_output_stream_streamcopy(ost);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// parse user provided disposition, and update stream values</span></span><br><span class="line">    <span class="keyword">if</span> (ost-&gt;disposition) &#123;</span><br><span class="line">        <span class="keyword">static</span> <span class="keyword">const</span> AVOption opts[] = &#123;</span><br><span class="line">            &#123; <span class="string">&quot;disposition&quot;</span>         , <span class="literal">NULL</span>, <span class="number">0</span>, AV_OPT_TYPE_FLAGS, &#123; .i64 = <span class="number">0</span> &#125;, INT64_MIN, INT64_MAX, .unit = <span class="string">&quot;flags&quot;</span> &#125;,</span><br><span class="line">            &#123; <span class="string">&quot;default&quot;</span>             , <span class="literal">NULL</span>, <span class="number">0</span>, AV_OPT_TYPE_CONST, &#123; .i64 = AV_DISPOSITION_DEFAULT           &#125;,    .unit = <span class="string">&quot;flags&quot;</span> &#125;,</span><br><span class="line">            &#123; <span class="string">&quot;dub&quot;</span>                 , <span class="literal">NULL</span>, <span class="number">0</span>, AV_OPT_TYPE_CONST, &#123; .i64 = AV_DISPOSITION_DUB               &#125;,    .unit = <span class="string">&quot;flags&quot;</span> &#125;,</span><br><span class="line">            &#123; <span class="string">&quot;original&quot;</span>            , <span class="literal">NULL</span>, <span class="number">0</span>, AV_OPT_TYPE_CONST, &#123; .i64 = AV_DISPOSITION_ORIGINAL          &#125;,    .unit = <span class="string">&quot;flags&quot;</span> &#125;,</span><br><span class="line">            &#123; <span class="string">&quot;comment&quot;</span>             , <span class="literal">NULL</span>, <span class="number">0</span>, AV_OPT_TYPE_CONST, &#123; .i64 = AV_DISPOSITION_COMMENT           &#125;,    .unit = <span class="string">&quot;flags&quot;</span> &#125;,</span><br><span class="line">            &#123; <span class="string">&quot;lyrics&quot;</span>              , <span class="literal">NULL</span>, <span class="number">0</span>, AV_OPT_TYPE_CONST, &#123; .i64 = AV_DISPOSITION_LYRICS            &#125;,    .unit = <span class="string">&quot;flags&quot;</span> &#125;,</span><br><span class="line">            &#123; <span class="string">&quot;karaoke&quot;</span>             , <span class="literal">NULL</span>, <span class="number">0</span>, AV_OPT_TYPE_CONST, &#123; .i64 = AV_DISPOSITION_KARAOKE           &#125;,    .unit = <span class="string">&quot;flags&quot;</span> &#125;,</span><br><span class="line">            &#123; <span class="string">&quot;forced&quot;</span>              , <span class="literal">NULL</span>, <span class="number">0</span>, AV_OPT_TYPE_CONST, &#123; .i64 = AV_DISPOSITION_FORCED            &#125;,    .unit = <span class="string">&quot;flags&quot;</span> &#125;,</span><br><span class="line">            &#123; <span class="string">&quot;hearing_impaired&quot;</span>    , <span class="literal">NULL</span>, <span class="number">0</span>, AV_OPT_TYPE_CONST, &#123; .i64 = AV_DISPOSITION_HEARING_IMPAIRED  &#125;,    .unit = <span class="string">&quot;flags&quot;</span> &#125;,</span><br><span class="line">            &#123; <span class="string">&quot;visual_impaired&quot;</span>     , <span class="literal">NULL</span>, <span class="number">0</span>, AV_OPT_TYPE_CONST, &#123; .i64 = AV_DISPOSITION_VISUAL_IMPAIRED   &#125;,    .unit = <span class="string">&quot;flags&quot;</span> &#125;,</span><br><span class="line">            &#123; <span class="string">&quot;clean_effects&quot;</span>       , <span class="literal">NULL</span>, <span class="number">0</span>, AV_OPT_TYPE_CONST, &#123; .i64 = AV_DISPOSITION_CLEAN_EFFECTS     &#125;,    .unit = <span class="string">&quot;flags&quot;</span> &#125;,</span><br><span class="line">            &#123; <span class="string">&quot;attached_pic&quot;</span>        , <span class="literal">NULL</span>, <span class="number">0</span>, AV_OPT_TYPE_CONST, &#123; .i64 = AV_DISPOSITION_ATTACHED_PIC      &#125;,    .unit = <span class="string">&quot;flags&quot;</span> &#125;,</span><br><span class="line">            &#123; <span class="string">&quot;captions&quot;</span>            , <span class="literal">NULL</span>, <span class="number">0</span>, AV_OPT_TYPE_CONST, &#123; .i64 = AV_DISPOSITION_CAPTIONS          &#125;,    .unit = <span class="string">&quot;flags&quot;</span> &#125;,</span><br><span class="line">            &#123; <span class="string">&quot;descriptions&quot;</span>        , <span class="literal">NULL</span>, <span class="number">0</span>, AV_OPT_TYPE_CONST, &#123; .i64 = AV_DISPOSITION_DESCRIPTIONS      &#125;,    .unit = <span class="string">&quot;flags&quot;</span> &#125;,</span><br><span class="line">            &#123; <span class="string">&quot;dependent&quot;</span>           , <span class="literal">NULL</span>, <span class="number">0</span>, AV_OPT_TYPE_CONST, &#123; .i64 = AV_DISPOSITION_DEPENDENT         &#125;,    .unit = <span class="string">&quot;flags&quot;</span> &#125;,</span><br><span class="line">            &#123; <span class="string">&quot;metadata&quot;</span>            , <span class="literal">NULL</span>, <span class="number">0</span>, AV_OPT_TYPE_CONST, &#123; .i64 = AV_DISPOSITION_METADATA          &#125;,    .unit = <span class="string">&quot;flags&quot;</span> &#125;,</span><br><span class="line">            &#123; <span class="literal">NULL</span> &#125;,</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="keyword">static</span> <span class="keyword">const</span> AVClass <span class="class"><span class="keyword">class</span> =</span> &#123;</span><br><span class="line">            .class_name = <span class="string">&quot;&quot;</span>,</span><br><span class="line">            .item_name  = av_default_item_name,</span><br><span class="line">            .option     = opts,</span><br><span class="line">            .version    = LIBAVUTIL_VERSION_INT,</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="keyword">const</span> AVClass *pclass = &amp;class;</span><br><span class="line"></span><br><span class="line">        ret = av_opt_eval_flags(&amp;pclass, &amp;opts[<span class="number">0</span>], ost-&gt;disposition, &amp;ost-&gt;st-&gt;disposition);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* initialize bitstream filters for the output stream</span></span><br><span class="line"><span class="comment">     * needs to be done here, because the codec id for streamcopy is not</span></span><br><span class="line"><span class="comment">     * known until now */</span></span><br><span class="line">    ret = init_output_bsfs(ost);</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line"></span><br><span class="line">    ost-&gt;initialized = <span class="number">1</span>;   <span class="comment">// 流被初始化</span></span><br><span class="line"></span><br><span class="line">    ret = check_init_output_file(output_files[ost-&gt;file_index], ost-&gt;file_index);</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> ret;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">report_new_stream</span><span class="params">(<span class="keyword">int</span> input_index, AVPacket *pkt)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    InputFile *file = input_files[input_index];</span><br><span class="line">    AVStream *st = file-&gt;ctx-&gt;streams[pkt-&gt;stream_index];</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (pkt-&gt;stream_index &lt; file-&gt;nb_streams_warn)</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    av_log(file-&gt;ctx, AV_LOG_WARNING,</span><br><span class="line">           <span class="string">&quot;New %s stream %d:%d at pos:%&quot;</span>PRId64<span class="string">&quot; and DTS:%ss\n&quot;</span>,</span><br><span class="line">           av_get_media_type_string(st-&gt;codecpar-&gt;codec_type),</span><br><span class="line">           input_index, pkt-&gt;stream_index,</span><br><span class="line">           pkt-&gt;pos, av_ts2timestr(pkt-&gt;dts, &amp;st-&gt;time_base));</span><br><span class="line">    file-&gt;nb_streams_warn = pkt-&gt;stream_index + <span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">transcode_init</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> ret = <span class="number">0</span>, i, j, k;</span><br><span class="line">    AVFormatContext *oc;    <span class="comment">// 输出流的编解码器结构</span></span><br><span class="line">    OutputStream *ost;      <span class="comment">// 输出流</span></span><br><span class="line">    InputStream *ist;       <span class="comment">// 输入流</span></span><br><span class="line">    <span class="keyword">char</span> error[<span class="number">1024</span>] = &#123;<span class="number">0</span>&#125;;</span><br><span class="line">    <span class="comment">// 初始化filter</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_filtergraphs; i++) &#123;</span><br><span class="line">        FilterGraph *fg = filtergraphs[i];</span><br><span class="line">        <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; fg-&gt;nb_outputs; j++) &#123;</span><br><span class="line">            OutputFilter *ofilter = fg-&gt;outputs[j];</span><br><span class="line">            <span class="keyword">if</span> (!ofilter-&gt;ost || ofilter-&gt;ost-&gt;source_index &gt;= <span class="number">0</span>)</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            <span class="keyword">if</span> (fg-&gt;nb_inputs != <span class="number">1</span>)</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            <span class="keyword">for</span> (k = nb_input_streams<span class="number">-1</span>; k &gt;= <span class="number">0</span> ; k--)</span><br><span class="line">                <span class="keyword">if</span> (fg-&gt;inputs[<span class="number">0</span>]-&gt;ist == input_streams[k])</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">            ofilter-&gt;ost-&gt;source_index = k;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 初始化输入文件, 文件打开</span></span><br><span class="line">    <span class="comment">/* init framerate emulation */</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_input_files; i++) &#123;</span><br><span class="line">        InputFile *ifile = input_files[i];  <span class="comment">// 查找对应的文件</span></span><br><span class="line">        <span class="keyword">if</span> (ifile-&gt;rate_emu)                <span class="comment">// 初始化帧率仿真，主要是实时推流的时候使用，可以按播放速度去推流</span></span><br><span class="line">            <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; ifile-&gt;nb_streams; j++) &#123;<span class="comment">// 初始化start时间</span></span><br><span class="line">                <span class="comment">// ifile-&gt;ist_index为 该file在input_streams数组的起始索引</span></span><br><span class="line">                input_streams[j + ifile-&gt;ist_index]-&gt;start = av_gettime_relative(); <span class="comment">// 记录起始时间</span></span><br><span class="line">            &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 初始化输入流</span></span><br><span class="line">    <span class="comment">/* init input streams */</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_input_streams; i++)</span><br><span class="line">        <span class="comment">// 每个流的都是独立处理</span></span><br><span class="line">        <span class="keyword">if</span> ((ret = init_input_stream(i, error, <span class="keyword">sizeof</span>(error))) &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_streams; i++) &#123;</span><br><span class="line">                ost = output_streams[i];</span><br><span class="line">                avcodec_close(ost-&gt;enc_ctx);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">goto</span> dump_format;</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="comment">// 初始化输出流，根据对应的输入流，设置其编码器的参数</span></span><br><span class="line">    <span class="comment">/* open each encoder */</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_streams; i++) &#123;</span><br><span class="line">        <span class="comment">// skip streams fed from filtergraphs until we have a frame for them</span></span><br><span class="line">        <span class="keyword">if</span> (output_streams[i]-&gt;filter)  <span class="comment">// filter先暂且不理会</span></span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        <span class="comment">// 初始化每个流</span></span><br><span class="line">        ret = init_output_stream(output_streams[i], error, <span class="keyword">sizeof</span>(error));</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">goto</span> dump_format;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* discard unused programs */</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_input_files; i++) &#123;</span><br><span class="line">        InputFile *ifile = input_files[i];</span><br><span class="line">        <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; ifile-&gt;ctx-&gt;nb_programs; j++) &#123;</span><br><span class="line">            AVProgram *p = ifile-&gt;ctx-&gt;programs[j];</span><br><span class="line">            <span class="keyword">int</span> discard  = AVDISCARD_ALL;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">for</span> (k = <span class="number">0</span>; k &lt; p-&gt;nb_stream_indexes; k++)</span><br><span class="line">                <span class="keyword">if</span> (!input_streams[ifile-&gt;ist_index + p-&gt;stream_index[k]]-&gt;discard) &#123;</span><br><span class="line">                    discard = AVDISCARD_DEFAULT;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            p-&gt;discard = discard;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* write headers for files with no streams */</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_files; i++) &#123;</span><br><span class="line">        oc = output_files[i]-&gt;ctx;</span><br><span class="line">        <span class="keyword">if</span> (oc-&gt;oformat-&gt;flags &amp; AVFMT_NOSTREAMS &amp;&amp; oc-&gt;nb_streams == <span class="number">0</span>) &#123;</span><br><span class="line">            ret = check_init_output_file(output_files[i], i);</span><br><span class="line">            <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">                <span class="keyword">goto</span> dump_format;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"> dump_format:</span><br><span class="line">    <span class="comment">/* dump the stream mapping */</span></span><br><span class="line">    av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;Stream mapping:\n&quot;</span>);</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_input_streams; i++) &#123;</span><br><span class="line">        ist = input_streams[i];</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; ist-&gt;nb_filters; j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (!filtergraph_is_simple(ist-&gt;filters[j]-&gt;graph)) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;  Stream #%d:%d (%s) -&gt; %s&quot;</span>,</span><br><span class="line">                       ist-&gt;file_index, ist-&gt;st-&gt;index, ist-&gt;dec ? ist-&gt;dec-&gt;name : <span class="string">&quot;?&quot;</span>,</span><br><span class="line">                       ist-&gt;filters[j]-&gt;name);</span><br><span class="line">                <span class="keyword">if</span> (nb_filtergraphs &gt; <span class="number">1</span>)</span><br><span class="line">                    av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot; (graph %d)&quot;</span>, ist-&gt;filters[j]-&gt;graph-&gt;index);</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;\n&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_streams; i++) &#123;</span><br><span class="line">        ost = output_streams[i];</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;attachment_filename) &#123;</span><br><span class="line">            <span class="comment">/* an attached file */</span></span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;  File %s -&gt; Stream #%d:%d\n&quot;</span>,</span><br><span class="line">                   ost-&gt;attachment_filename, ost-&gt;file_index, ost-&gt;index);</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;filter &amp;&amp; !filtergraph_is_simple(ost-&gt;filter-&gt;graph)) &#123;</span><br><span class="line">            <span class="comment">/* output from a complex graph */</span></span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;  %s&quot;</span>, ost-&gt;filter-&gt;name);</span><br><span class="line">            <span class="keyword">if</span> (nb_filtergraphs &gt; <span class="number">1</span>)</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot; (graph %d)&quot;</span>, ost-&gt;filter-&gt;graph-&gt;index);</span><br><span class="line"></span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot; -&gt; Stream #%d:%d (%s)\n&quot;</span>, ost-&gt;file_index,</span><br><span class="line">                   ost-&gt;index, ost-&gt;enc ? ost-&gt;enc-&gt;name : <span class="string">&quot;?&quot;</span>);</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;  Stream #%d:%d -&gt; #%d:%d&quot;</span>,</span><br><span class="line">               input_streams[ost-&gt;source_index]-&gt;file_index,</span><br><span class="line">               input_streams[ost-&gt;source_index]-&gt;st-&gt;index,</span><br><span class="line">               ost-&gt;file_index,</span><br><span class="line">               ost-&gt;index);</span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;sync_ist != input_streams[ost-&gt;source_index])</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot; [sync #%d:%d]&quot;</span>,</span><br><span class="line">                   ost-&gt;sync_ist-&gt;file_index,</span><br><span class="line">                   ost-&gt;sync_ist-&gt;st-&gt;index);</span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;stream_copy)</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot; (copy)&quot;</span>);</span><br><span class="line">        <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">const</span> AVCodec *in_codec    = input_streams[ost-&gt;source_index]-&gt;dec;</span><br><span class="line">            <span class="keyword">const</span> AVCodec *out_codec   = ost-&gt;enc;</span><br><span class="line">            <span class="keyword">const</span> <span class="keyword">char</span> *decoder_name   = <span class="string">&quot;?&quot;</span>;</span><br><span class="line">            <span class="keyword">const</span> <span class="keyword">char</span> *in_codec_name  = <span class="string">&quot;?&quot;</span>;</span><br><span class="line">            <span class="keyword">const</span> <span class="keyword">char</span> *encoder_name   = <span class="string">&quot;?&quot;</span>;</span><br><span class="line">            <span class="keyword">const</span> <span class="keyword">char</span> *out_codec_name = <span class="string">&quot;?&quot;</span>;</span><br><span class="line">            <span class="keyword">const</span> AVCodecDescriptor *desc;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (in_codec) &#123;</span><br><span class="line">                decoder_name  = in_codec-&gt;name;</span><br><span class="line">                desc = avcodec_descriptor_get(in_codec-&gt;id);</span><br><span class="line">                <span class="keyword">if</span> (desc)</span><br><span class="line">                    in_codec_name = desc-&gt;name;</span><br><span class="line">                <span class="keyword">if</span> (!<span class="built_in">strcmp</span>(decoder_name, in_codec_name))</span><br><span class="line">                    decoder_name = <span class="string">&quot;native&quot;</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (out_codec) &#123;</span><br><span class="line">                encoder_name   = out_codec-&gt;name;</span><br><span class="line">                desc = avcodec_descriptor_get(out_codec-&gt;id);</span><br><span class="line">                <span class="keyword">if</span> (desc)</span><br><span class="line">                    out_codec_name = desc-&gt;name;</span><br><span class="line">                <span class="keyword">if</span> (!<span class="built_in">strcmp</span>(encoder_name, out_codec_name))</span><br><span class="line">                    encoder_name = <span class="string">&quot;native&quot;</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot; (%s (%s) -&gt; %s (%s))&quot;</span>,</span><br><span class="line">                   in_codec_name, decoder_name,</span><br><span class="line">                   out_codec_name, encoder_name);</span><br><span class="line">        &#125;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;\n&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ret) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;%s\n&quot;</span>, error);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    atomic_store(&amp;transcode_init_done, <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* Return 1 if there remain streams where more output is wanted, 0 otherwise. */</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">need_output</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_streams; i++) &#123;</span><br><span class="line">        OutputStream *ost    = output_streams[i];</span><br><span class="line">        OutputFile *of       = output_files[ost-&gt;file_index];</span><br><span class="line">        AVFormatContext *os  = output_files[ost-&gt;file_index]-&gt;ctx;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;finished ||</span><br><span class="line">            (os-&gt;pb &amp;&amp; avio_tell(os-&gt;pb) &gt;= of-&gt;limit_filesize))</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;frame_number &gt;= ost-&gt;max_frames) &#123;</span><br><span class="line">            <span class="keyword">int</span> j;</span><br><span class="line">            <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; of-&gt;ctx-&gt;nb_streams; j++)</span><br><span class="line">                close_output_stream(output_streams[of-&gt;ost_index + j]);</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Select the output stream to process. 选择时间戳小的输出流</span></span><br><span class="line"><span class="comment"> * 为什么要选择最小的呢？是为了输出流能够统一进度？</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * @return  selected output stream, or NULL if none available</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> OutputStream *<span class="title">choose_output</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i;</span><br><span class="line">    <span class="keyword">int64_t</span> opts_min = INT64_MAX;</span><br><span class="line">    OutputStream *ost_min = <span class="literal">NULL</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_streams; i++) &#123;</span><br><span class="line">        OutputStream *ost = output_streams[i];</span><br><span class="line">        <span class="comment">// 转换成微妙</span></span><br><span class="line">        <span class="keyword">int64_t</span> opts = ost-&gt;st-&gt;cur_dts == AV_NOPTS_VALUE ? INT64_MIN :</span><br><span class="line">                       av_rescale_q(ost-&gt;st-&gt;cur_dts, ost-&gt;st-&gt;time_base,</span><br><span class="line">                                    AV_TIME_BASE_Q);</span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;st-&gt;cur_dts == AV_NOPTS_VALUE)</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_DEBUG,</span><br><span class="line">                <span class="string">&quot;cur_dts is invalid st:%d (%d) [init:%d i_done:%d finish:%d] (this is harmless if it occurs once at the start per stream)\n&quot;</span>,</span><br><span class="line">                ost-&gt;st-&gt;index, ost-&gt;st-&gt;id, ost-&gt;initialized, ost-&gt;inputs_done, ost-&gt;finished);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!ost-&gt;initialized &amp;&amp; !ost-&gt;inputs_done) <span class="comment">// 如果没有初始化则直接返回该流</span></span><br><span class="line">            <span class="keyword">return</span> ost;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!ost-&gt;finished &amp;&amp; opts &lt; opts_min) &#123;    <span class="comment">// stream没有结束且小于最小的opts_min</span></span><br><span class="line">            opts_min = opts;</span><br><span class="line">            ost_min  = ost-&gt;unavailable ? <span class="literal">NULL</span> : ost;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> ost_min;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">set_tty_echo</span><span class="params">(<span class="keyword">int</span> on)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_TERMIOS_H</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">termios</span> <span class="title">tty</span>;</span></span><br><span class="line">    <span class="keyword">if</span> (tcgetattr(<span class="number">0</span>, &amp;tty) == <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">if</span> (on) tty.c_lflag |= ECHO;</span><br><span class="line">        <span class="keyword">else</span>    tty.c_lflag &amp;= ~ECHO;</span><br><span class="line">        tcsetattr(<span class="number">0</span>, TCSANOW, &amp;tty);</span><br><span class="line">    &#125;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">check_keyboard_interaction</span><span class="params">(<span class="keyword">int64_t</span> cur_time)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i, ret, key;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int64_t</span> last_time;</span><br><span class="line">    <span class="keyword">if</span> (received_nb_signals)</span><br><span class="line">        <span class="keyword">return</span> AVERROR_EXIT;</span><br><span class="line">    <span class="comment">/* read_key() returns 0 on EOF */</span></span><br><span class="line">    <span class="keyword">if</span>(cur_time - last_time &gt;= <span class="number">100000</span> &amp;&amp; !run_as_daemon)&#123;</span><br><span class="line">        key =  read_key();</span><br><span class="line">        last_time = cur_time;</span><br><span class="line">    &#125;<span class="keyword">else</span></span><br><span class="line">        key = <span class="number">-1</span>;</span><br><span class="line">    <span class="keyword">if</span> (key == <span class="string">&#x27;q&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> AVERROR_EXIT;</span><br><span class="line">    <span class="keyword">if</span> (key == <span class="string">&#x27;+&#x27;</span>) av_log_set_level(av_log_get_level()+<span class="number">10</span>);</span><br><span class="line">    <span class="keyword">if</span> (key == <span class="string">&#x27;-&#x27;</span>) av_log_set_level(av_log_get_level()<span class="number">-10</span>);</span><br><span class="line">    <span class="keyword">if</span> (key == <span class="string">&#x27;s&#x27;</span>) qp_hist     ^= <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">if</span> (key == <span class="string">&#x27;h&#x27;</span>)&#123;</span><br><span class="line">        <span class="keyword">if</span> (do_hex_dump)&#123;</span><br><span class="line">            do_hex_dump = do_pkt_dump = <span class="number">0</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span>(do_pkt_dump)&#123;</span><br><span class="line">            do_hex_dump = <span class="number">1</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span></span><br><span class="line">            do_pkt_dump = <span class="number">1</span>;</span><br><span class="line">        av_log_set_level(AV_LOG_DEBUG);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (key == <span class="string">&#x27;c&#x27;</span> || key == <span class="string">&#x27;C&#x27;</span>)&#123;</span><br><span class="line">        <span class="keyword">char</span> buf[<span class="number">4096</span>], target[<span class="number">64</span>], command[<span class="number">256</span>], arg[<span class="number">256</span>] = &#123;<span class="number">0</span>&#125;;</span><br><span class="line">        <span class="keyword">double</span> time;</span><br><span class="line">        <span class="keyword">int</span> k, n = <span class="number">0</span>;</span><br><span class="line">        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">&quot;\nEnter command: &lt;target&gt;|all &lt;time&gt;|-1 &lt;command&gt;[ &lt;argument&gt;]\n&quot;</span>);</span><br><span class="line">        i = <span class="number">0</span>;</span><br><span class="line">        set_tty_echo(<span class="number">1</span>);</span><br><span class="line">        <span class="keyword">while</span> ((k = read_key()) != <span class="string">&#x27;\n&#x27;</span> &amp;&amp; k != <span class="string">&#x27;\r&#x27;</span> &amp;&amp; i &lt; <span class="keyword">sizeof</span>(buf)<span class="number">-1</span>)</span><br><span class="line">            <span class="keyword">if</span> (k &gt; <span class="number">0</span>)</span><br><span class="line">                buf[i++] = k;</span><br><span class="line">        buf[i] = <span class="number">0</span>;</span><br><span class="line">        set_tty_echo(<span class="number">0</span>);</span><br><span class="line">        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">&quot;\n&quot;</span>);</span><br><span class="line">        <span class="keyword">if</span> (k &gt; <span class="number">0</span> &amp;&amp;</span><br><span class="line">            (n = <span class="built_in">sscanf</span>(buf, <span class="string">&quot;%63[^ ] %lf %255[^ ] %255[^\n]&quot;</span>, target, &amp;time, command, arg)) &gt;= <span class="number">3</span>) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_DEBUG, <span class="string">&quot;Processing command target:%s time:%f command:%s arg:%s&quot;</span>,</span><br><span class="line">                   target, time, command, arg);</span><br><span class="line">            <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_filtergraphs; i++) &#123;</span><br><span class="line">                FilterGraph *fg = filtergraphs[i];</span><br><span class="line">                <span class="keyword">if</span> (fg-&gt;graph) &#123;</span><br><span class="line">                    <span class="keyword">if</span> (time &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                        ret = avfilter_graph_send_command(fg-&gt;graph, target, command, arg, buf, <span class="keyword">sizeof</span>(buf),</span><br><span class="line">                                                          key == <span class="string">&#x27;c&#x27;</span> ? AVFILTER_CMD_FLAG_ONE : <span class="number">0</span>);</span><br><span class="line">                        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">&quot;Command reply for stream %d: ret:%d res:\n%s&quot;</span>, i, ret, buf);</span><br><span class="line">                    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (key == <span class="string">&#x27;c&#x27;</span>) &#123;</span><br><span class="line">                        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">&quot;Queuing commands only on filters supporting the specific command is unsupported\n&quot;</span>);</span><br><span class="line">                        ret = AVERROR_PATCHWELCOME;</span><br><span class="line">                    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                        ret = avfilter_graph_queue_command(fg-&gt;graph, target, command, arg, <span class="number">0</span>, time);</span><br><span class="line">                        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">                            <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">&quot;Queuing command failed with error %s\n&quot;</span>, av_err2str(ret));</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_ERROR,</span><br><span class="line">                   <span class="string">&quot;Parse error, at least 3 arguments were expected, &quot;</span></span><br><span class="line">                   <span class="string">&quot;only %d given in string &#x27;%s&#x27;\n&quot;</span>, n, buf);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (key == <span class="string">&#x27;d&#x27;</span> || key == <span class="string">&#x27;D&#x27;</span>)&#123;</span><br><span class="line">        <span class="keyword">int</span> debug=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">if</span>(key == <span class="string">&#x27;D&#x27;</span>) &#123;</span><br><span class="line">            debug = input_streams[<span class="number">0</span>]-&gt;st-&gt;codec-&gt;debug&lt;&lt;<span class="number">1</span>;</span><br><span class="line">            <span class="keyword">if</span>(!debug) debug = <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">while</span>(debug &amp; (FF_DEBUG_DCT_COEFF</span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> FF_API_DEBUG_MV</span></span><br><span class="line">                                             |FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line">                                                                                  )) <span class="comment">//unsupported, would just crash</span></span><br><span class="line">                debug += debug;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">char</span> buf[<span class="number">32</span>];</span><br><span class="line">            <span class="keyword">int</span> k = <span class="number">0</span>;</span><br><span class="line">            i = <span class="number">0</span>;</span><br><span class="line">            set_tty_echo(<span class="number">1</span>);</span><br><span class="line">            <span class="keyword">while</span> ((k = read_key()) != <span class="string">&#x27;\n&#x27;</span> &amp;&amp; k != <span class="string">&#x27;\r&#x27;</span> &amp;&amp; i &lt; <span class="keyword">sizeof</span>(buf)<span class="number">-1</span>)</span><br><span class="line">                <span class="keyword">if</span> (k &gt; <span class="number">0</span>)</span><br><span class="line">                    buf[i++] = k;</span><br><span class="line">            buf[i] = <span class="number">0</span>;</span><br><span class="line">            set_tty_echo(<span class="number">0</span>);</span><br><span class="line">            <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">&quot;\n&quot;</span>);</span><br><span class="line">            <span class="keyword">if</span> (k &lt;= <span class="number">0</span> || <span class="built_in">sscanf</span>(buf, <span class="string">&quot;%d&quot;</span>, &amp;debug)!=<span class="number">1</span>)</span><br><span class="line">                <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>,<span class="string">&quot;error parsing debug value\n&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(i=<span class="number">0</span>;i&lt;nb_input_streams;i++) &#123;</span><br><span class="line">            input_streams[i]-&gt;st-&gt;codec-&gt;debug = debug;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(i=<span class="number">0</span>;i&lt;nb_output_streams;i++) &#123;</span><br><span class="line">            OutputStream *ost = output_streams[i];</span><br><span class="line">            ost-&gt;enc_ctx-&gt;debug = debug;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(debug) av_log_set_level(AV_LOG_DEBUG);</span><br><span class="line">        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>,<span class="string">&quot;debug=%d\n&quot;</span>, debug);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (key == <span class="string">&#x27;?&#x27;</span>)&#123;</span><br><span class="line">        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">&quot;key    function\n&quot;</span></span><br><span class="line">                        <span class="string">&quot;?      show this help\n&quot;</span></span><br><span class="line">                        <span class="string">&quot;+      increase verbosity\n&quot;</span></span><br><span class="line">                        <span class="string">&quot;-      decrease verbosity\n&quot;</span></span><br><span class="line">                        <span class="string">&quot;c      Send command to first matching filter supporting it\n&quot;</span></span><br><span class="line">                        <span class="string">&quot;C      Send/Queue command to all matching filters\n&quot;</span></span><br><span class="line">                        <span class="string">&quot;D      cycle through available debug modes\n&quot;</span></span><br><span class="line">                        <span class="string">&quot;h      dump packets/hex press to cycle through the 3 states\n&quot;</span></span><br><span class="line">                        <span class="string">&quot;q      quit\n&quot;</span></span><br><span class="line">                        <span class="string">&quot;s      Show QP histogram\n&quot;</span></span><br><span class="line">        );</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_THREADS</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> *<span class="title">input_thread</span><span class="params">(<span class="keyword">void</span> *arg)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    InputFile *f = arg;</span><br><span class="line">    <span class="keyword">unsigned</span> flags = f-&gt;non_blocking ? AV_THREAD_MESSAGE_NONBLOCK : <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> ret = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span> (<span class="number">1</span>) &#123;</span><br><span class="line">        AVPacket pkt;</span><br><span class="line">        ret = av_read_frame(f-&gt;ctx, &amp;pkt);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (ret == AVERROR(EAGAIN)) &#123;</span><br><span class="line">            av_usleep(<span class="number">10000</span>);</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            av_thread_message_queue_set_err_recv(f-&gt;in_thread_queue, ret);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        ret = av_thread_message_queue_send(f-&gt;in_thread_queue, &amp;pkt, flags);</span><br><span class="line">        <span class="keyword">if</span> (flags &amp;&amp; ret == AVERROR(EAGAIN)) &#123;</span><br><span class="line">            flags = <span class="number">0</span>;</span><br><span class="line">            ret = av_thread_message_queue_send(f-&gt;in_thread_queue, &amp;pkt, flags);</span><br><span class="line">            av_log(f-&gt;ctx, AV_LOG_WARNING,</span><br><span class="line">                   <span class="string">&quot;Thread message queue blocking; consider raising the &quot;</span></span><br><span class="line">                   <span class="string">&quot;thread_queue_size option (current value: %d)\n&quot;</span>,</span><br><span class="line">                   f-&gt;thread_queue_size);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (ret != AVERROR_EOF)</span><br><span class="line">                av_log(f-&gt;ctx, AV_LOG_ERROR,</span><br><span class="line">                       <span class="string">&quot;Unable to send packet to main thread: %s\n&quot;</span>,</span><br><span class="line">                       av_err2str(ret));</span><br><span class="line">            av_packet_unref(&amp;pkt);</span><br><span class="line">            av_thread_message_queue_set_err_recv(f-&gt;in_thread_queue, ret);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">free_input_thread</span><span class="params">(<span class="keyword">int</span> i)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    InputFile *f = input_files[i];</span><br><span class="line">    AVPacket pkt;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!f || !f-&gt;in_thread_queue)</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    av_thread_message_queue_set_err_send(f-&gt;in_thread_queue, AVERROR_EOF);</span><br><span class="line">    <span class="keyword">while</span> (av_thread_message_queue_recv(f-&gt;in_thread_queue, &amp;pkt, <span class="number">0</span>) &gt;= <span class="number">0</span>)</span><br><span class="line">        av_packet_unref(&amp;pkt);</span><br><span class="line"></span><br><span class="line">    pthread_join(f-&gt;thread, <span class="literal">NULL</span>);</span><br><span class="line">    f-&gt;joined = <span class="number">1</span>;</span><br><span class="line">    av_thread_message_queue_free(&amp;f-&gt;in_thread_queue);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">free_input_threads</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_input_files; i++)</span><br><span class="line">        free_input_thread(i);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">init_input_thread</span><span class="params">(<span class="keyword">int</span> i)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> ret;</span><br><span class="line">    InputFile *f = input_files[i];</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (nb_input_files == <span class="number">1</span>)</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (f-&gt;ctx-&gt;pb ? !f-&gt;ctx-&gt;pb-&gt;seekable :</span><br><span class="line">        <span class="built_in">strcmp</span>(f-&gt;ctx-&gt;iformat-&gt;name, <span class="string">&quot;lavfi&quot;</span>))</span><br><span class="line">        f-&gt;non_blocking = <span class="number">1</span>;</span><br><span class="line">    ret = av_thread_message_queue_alloc(&amp;f-&gt;in_thread_queue,</span><br><span class="line">                                        f-&gt;thread_queue_size, <span class="keyword">sizeof</span>(AVPacket));</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> ((ret = pthread_create(&amp;f-&gt;thread, <span class="literal">NULL</span>, input_thread, f))) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;pthread_create failed: %s. Try to increase `ulimit -v` or decrease `ulimit -s`.\n&quot;</span>, strerror(ret));</span><br><span class="line">        av_thread_message_queue_free(&amp;f-&gt;in_thread_queue);</span><br><span class="line">        <span class="keyword">return</span> AVERROR(ret);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">init_input_threads</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i, ret;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_input_files; i++) &#123;</span><br><span class="line">        ret = init_input_thread(i);</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">get_input_packet_mt</span><span class="params">(InputFile *f, AVPacket *pkt)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> av_thread_message_queue_recv(f-&gt;in_thread_queue, pkt,</span><br><span class="line">                                        f-&gt;non_blocking ?</span><br><span class="line">                                        AV_THREAD_MESSAGE_NONBLOCK : <span class="number">0</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">get_input_packet</span><span class="params">(InputFile *f, AVPacket *pkt)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (f-&gt;rate_emu) &#123;</span><br><span class="line">        <span class="keyword">int</span> i;</span><br><span class="line">        <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; f-&gt;nb_streams; i++) &#123;</span><br><span class="line">            InputStream *ist = input_streams[f-&gt;ist_index + i];</span><br><span class="line">            <span class="keyword">int64_t</span> pts = av_rescale(ist-&gt;dts, <span class="number">1000000</span>, AV_TIME_BASE);</span><br><span class="line">            <span class="keyword">int64_t</span> now = av_gettime_relative() - ist-&gt;start;</span><br><span class="line">            <span class="keyword">if</span> (pts &gt; now)</span><br><span class="line">                <span class="keyword">return</span> AVERROR(EAGAIN);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_THREADS</span></span><br><span class="line">    <span class="keyword">if</span> (nb_input_files &gt; <span class="number">1</span>)</span><br><span class="line">        <span class="keyword">return</span> get_input_packet_mt(f, pkt);</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line">    <span class="keyword">return</span> av_read_frame(f-&gt;ctx, pkt); <span class="comment">// 先关注这里的逻辑</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">got_eagain</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i;</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_streams; i++)</span><br><span class="line">        <span class="keyword">if</span> (output_streams[i]-&gt;unavailable)</span><br><span class="line">            <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">reset_eagain</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i;</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_input_files; i++)</span><br><span class="line">        input_files[i]-&gt;eagain = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_streams; i++)</span><br><span class="line">        output_streams[i]-&gt;unavailable = <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// set duration to max(tmp, duration) in a proper time base and return duration&#x27;s time_base</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> AVRational <span class="title">duration_max</span><span class="params">(<span class="keyword">int64_t</span> tmp, <span class="keyword">int64_t</span> *duration, AVRational tmp_time_base,</span></span></span><br><span class="line"><span class="function"><span class="params">                               AVRational time_base)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> ret;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!*duration) &#123;</span><br><span class="line">        *duration = tmp;</span><br><span class="line">        <span class="keyword">return</span> tmp_time_base;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    ret = av_compare_ts(*duration, time_base, tmp, tmp_time_base);</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">        *duration = tmp;</span><br><span class="line">        <span class="keyword">return</span> tmp_time_base;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> time_base;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">seek_to_start</span><span class="params">(InputFile *ifile, AVFormatContext *is)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    InputStream *ist;</span><br><span class="line">    AVCodecContext *avctx;</span><br><span class="line">    <span class="keyword">int</span> i, ret, has_audio = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int64_t</span> duration = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    ret = av_seek_frame(is, <span class="number">-1</span>, is-&gt;start_time, <span class="number">0</span>);</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; ifile-&gt;nb_streams; i++) &#123;</span><br><span class="line">        ist   = input_streams[ifile-&gt;ist_index + i];</span><br><span class="line">        avctx = ist-&gt;dec_ctx;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/* duration is the length of the last frame in a stream</span></span><br><span class="line"><span class="comment">         * when audio stream is present we don&#x27;t care about</span></span><br><span class="line"><span class="comment">         * last video frame length because it&#x27;s not defined exactly */</span></span><br><span class="line">        <span class="keyword">if</span> (avctx-&gt;codec_type == AVMEDIA_TYPE_AUDIO &amp;&amp; ist-&gt;nb_samples)</span><br><span class="line">            has_audio = <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; ifile-&gt;nb_streams; i++) &#123;</span><br><span class="line">        ist   = input_streams[ifile-&gt;ist_index + i];</span><br><span class="line">        avctx = ist-&gt;dec_ctx;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (has_audio) &#123;</span><br><span class="line">            <span class="keyword">if</span> (avctx-&gt;codec_type == AVMEDIA_TYPE_AUDIO &amp;&amp; ist-&gt;nb_samples) &#123;</span><br><span class="line">                AVRational sample_rate = &#123;<span class="number">1</span>, avctx-&gt;sample_rate&#125;;</span><br><span class="line"></span><br><span class="line">                duration = av_rescale_q(ist-&gt;nb_samples, sample_rate, ist-&gt;st-&gt;time_base);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (ist-&gt;framerate.num) &#123;</span><br><span class="line">                duration = av_rescale_q(<span class="number">1</span>, av_inv_q(ist-&gt;framerate), ist-&gt;st-&gt;time_base);</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (ist-&gt;st-&gt;avg_frame_rate.num) &#123;</span><br><span class="line">                duration = av_rescale_q(<span class="number">1</span>, av_inv_q(ist-&gt;st-&gt;avg_frame_rate), ist-&gt;st-&gt;time_base);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                duration = <span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (!ifile-&gt;duration)</span><br><span class="line">            ifile-&gt;time_base = ist-&gt;st-&gt;time_base;</span><br><span class="line">        <span class="comment">/* the total duration of the stream, max_pts - min_pts is</span></span><br><span class="line"><span class="comment">         * the duration of the stream without the last frame */</span></span><br><span class="line">        duration += ist-&gt;max_pts - ist-&gt;min_pts;</span><br><span class="line">        ifile-&gt;time_base = duration_max(duration, &amp;ifile-&gt;duration, ist-&gt;st-&gt;time_base,</span><br><span class="line">                                        ifile-&gt;time_base);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ifile-&gt;loop &gt; <span class="number">0</span>)</span><br><span class="line">        ifile-&gt;loop--;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> ret;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * Return 获取得到的包</span></span><br><span class="line"><span class="comment"> * - 0 -- one packet was read and processed</span></span><br><span class="line"><span class="comment"> * - AVERROR(EAGAIN) -- no packets were available for selected file,</span></span><br><span class="line"><span class="comment"> *   this function should be called again</span></span><br><span class="line"><span class="comment"> * - AVERROR_EOF -- this function should not be called again</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">process_input</span><span class="params">(<span class="keyword">int</span> file_index)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    InputFile *ifile = input_files[file_index];</span><br><span class="line">    AVFormatContext *is;</span><br><span class="line">    InputStream *ist;</span><br><span class="line">    AVPacket pkt;</span><br><span class="line">    <span class="keyword">int</span> ret, thread_ret, i, j;</span><br><span class="line">    <span class="keyword">int64_t</span> duration;</span><br><span class="line">    <span class="keyword">int64_t</span> pkt_dts;</span><br><span class="line"></span><br><span class="line">    is  = ifile-&gt;ctx;</span><br><span class="line">    ret = get_input_packet(ifile, &amp;pkt);    <span class="comment">// 读取packet， 此时是AVStream-&gt;time_base</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ret == AVERROR(EAGAIN)) &#123;</span><br><span class="line">        ifile-&gt;eagain = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span> &amp;&amp; ifile-&gt;loop) &#123;   <span class="comment">// 且需要loop被置为1</span></span><br><span class="line">        AVCodecContext *avctx;</span><br><span class="line">        <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; ifile-&gt;nb_streams; i++) &#123;</span><br><span class="line">            ist = input_streams[ifile-&gt;ist_index + i];</span><br><span class="line">            avctx = ist-&gt;dec_ctx;</span><br><span class="line">            <span class="keyword">if</span> (ist-&gt;decoding_needed) &#123;</span><br><span class="line">                ret = process_input_packet(ist, <span class="literal">NULL</span>, <span class="number">1</span>);</span><br><span class="line">                <span class="keyword">if</span> (ret&gt;<span class="number">0</span>)</span><br><span class="line">                    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">                avcodec_flush_buffers(avctx);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_THREADS</span></span><br><span class="line">        free_input_thread(file_index);</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line">        ret = seek_to_start(ifile, is);</span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_THREADS</span></span><br><span class="line">        thread_ret = init_input_thread(file_index);</span><br><span class="line">        <span class="keyword">if</span> (thread_ret &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> thread_ret;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_WARNING, <span class="string">&quot;Seek to start failed.\n&quot;</span>);</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">            ret = get_input_packet(ifile, &amp;pkt);</span><br><span class="line">        <span class="keyword">if</span> (ret == AVERROR(EAGAIN)) &#123;</span><br><span class="line">            ifile-&gt;eagain = <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">if</span> (ret != AVERROR_EOF) &#123;   <span class="comment">// &lt;0且不是数据读取完毕</span></span><br><span class="line">            print_error(is-&gt;url, ret);  <span class="comment">// 则报告错误状态</span></span><br><span class="line">            <span class="keyword">if</span> (exit_on_error)      <span class="comment">// exit_on_error==1则错误时结束程序</span></span><br><span class="line">                exit_program(<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; ifile-&gt;nb_streams; i++) &#123;</span><br><span class="line">            ist = input_streams[ifile-&gt;ist_index + i];</span><br><span class="line">            <span class="keyword">if</span> (ist-&gt;decoding_needed) &#123;</span><br><span class="line">                ret = process_input_packet(ist, <span class="literal">NULL</span>, <span class="number">0</span>);       <span class="comment">// 通知没有数据包可读了</span></span><br><span class="line">                <span class="keyword">if</span> (ret&gt;<span class="number">0</span>)</span><br><span class="line">                    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="comment">/* mark all outputs that don&#x27;t go through lavfi as finished */</span></span><br><span class="line">            <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; nb_output_streams; j++) &#123;</span><br><span class="line">                OutputStream *ost = output_streams[j];</span><br><span class="line"></span><br><span class="line">                <span class="keyword">if</span> (ost-&gt;source_index == ifile-&gt;ist_index + i &amp;&amp;</span><br><span class="line">                    (ost-&gt;stream_copy || ost-&gt;enc-&gt;type == AVMEDIA_TYPE_SUBTITLE)) <span class="comment">// 注意成立的条件</span></span><br><span class="line">                    finish_output_stream(ost);  <span class="comment">// 冲刷输出流</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        ifile-&gt;eof_reached = <span class="number">1</span>;     <span class="comment">// 读取完毕</span></span><br><span class="line">        <span class="keyword">return</span> AVERROR(EAGAIN);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    reset_eagain();     <span class="comment">// 能正常往下执行则重置eagain为0</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (do_pkt_dump) &#123;</span><br><span class="line">        av_pkt_dump_log2(<span class="literal">NULL</span>, AV_LOG_INFO, &amp;pkt, do_hex_dump,</span><br><span class="line">                         is-&gt;streams[pkt.stream_index]);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">/* the following test is needed in case new streams appear</span></span><br><span class="line"><span class="comment">       dynamically in stream : we ignore them */</span></span><br><span class="line">    <span class="keyword">if</span> (pkt.stream_index &gt;= ifile-&gt;nb_streams) &#123;</span><br><span class="line">        report_new_stream(file_index, &amp;pkt);</span><br><span class="line">        <span class="keyword">goto</span> discard_packet;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 获知我们是属于哪个输入流的</span></span><br><span class="line">    ist = input_streams[ifile-&gt;ist_index + pkt.stream_index];</span><br><span class="line"></span><br><span class="line">    ist-&gt;data_size += pkt.size; <span class="comment">// 做统计操作</span></span><br><span class="line">    ist-&gt;nb_packets++;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ist-&gt;discard)</span><br><span class="line">        <span class="keyword">goto</span> discard_packet;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (pkt.flags &amp; AV_PKT_FLAG_CORRUPT) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING,</span><br><span class="line">               <span class="string">&quot;%s: corrupt input packet in stream %d\n&quot;</span>, is-&gt;url, pkt.stream_index);</span><br><span class="line">        <span class="keyword">if</span> (exit_on_error)</span><br><span class="line">            exit_program(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (debug_ts) &#123; <span class="comment">// 可以看起debug时间戳 通过-debug_ts 1</span></span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;demuxer -&gt; ist_index:%d type:%s &quot;</span></span><br><span class="line">               <span class="string">&quot;next_dts:%s next_dts_time:%s next_pts:%s next_pts_time:%s pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s off:%s off_time:%s\n&quot;</span>,</span><br><span class="line">               ifile-&gt;ist_index + pkt.stream_index, av_get_media_type_string(ist-&gt;dec_ctx-&gt;codec_type),</span><br><span class="line">               av_ts2str(ist-&gt;next_dts), av_ts2timestr(ist-&gt;next_dts, &amp;AV_TIME_BASE_Q),</span><br><span class="line">               av_ts2str(ist-&gt;next_pts), av_ts2timestr(ist-&gt;next_pts, &amp;AV_TIME_BASE_Q),</span><br><span class="line">               av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &amp;ist-&gt;st-&gt;time_base),</span><br><span class="line">               av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &amp;ist-&gt;st-&gt;time_base),</span><br><span class="line">               av_ts2str(input_files[ist-&gt;file_index]-&gt;ts_offset),</span><br><span class="line">               av_ts2timestr(input_files[ist-&gt;file_index]-&gt;ts_offset, &amp;AV_TIME_BASE_Q));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 起始时间</span></span><br><span class="line">    <span class="keyword">if</span>(!ist-&gt;wrap_correction_done &amp;&amp; is-&gt;start_time != AV_NOPTS_VALUE &amp;&amp; ist-&gt;st-&gt;pts_wrap_bits &lt; <span class="number">64</span>)&#123;</span><br><span class="line">        <span class="keyword">int64_t</span> stime, stime2;</span><br><span class="line">        <span class="comment">// Correcting starttime based on the enabled streams</span></span><br><span class="line">        <span class="comment">// FIXME this ideally should be done before the first use of starttime but we do not know which are the enabled streams at that point.</span></span><br><span class="line">        <span class="comment">//       so we instead do it here as part of discontinuity handling</span></span><br><span class="line">        <span class="keyword">if</span> (   ist-&gt;next_dts == AV_NOPTS_VALUE</span><br><span class="line">            &amp;&amp; ifile-&gt;ts_offset == -is-&gt;start_time</span><br><span class="line">            &amp;&amp; (is-&gt;iformat-&gt;flags &amp; AVFMT_TS_DISCONT)) &#123;</span><br><span class="line">            <span class="keyword">int64_t</span> new_start_time = INT64_MAX;</span><br><span class="line">            <span class="keyword">for</span> (i=<span class="number">0</span>; i&lt;is-&gt;nb_streams; i++) &#123;</span><br><span class="line">                AVStream *st = is-&gt;streams[i];</span><br><span class="line">                <span class="keyword">if</span>(st-&gt;discard == AVDISCARD_ALL || st-&gt;start_time == AV_NOPTS_VALUE)</span><br><span class="line">                    <span class="keyword">continue</span>;</span><br><span class="line">                new_start_time = FFMIN(new_start_time, av_rescale_q(st-&gt;start_time, st-&gt;time_base, AV_TIME_BASE_Q));</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (new_start_time &gt; is-&gt;start_time) &#123;</span><br><span class="line">                av_log(is, AV_LOG_VERBOSE, <span class="string">&quot;Correcting start time by %&quot;</span>PRId64<span class="string">&quot;\n&quot;</span>, new_start_time - is-&gt;start_time);</span><br><span class="line">                ifile-&gt;ts_offset = -new_start_time;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 将起始时间换算成AVSteam-&gt;time_base</span></span><br><span class="line">        stime = av_rescale_q(is-&gt;start_time, AV_TIME_BASE_Q, ist-&gt;st-&gt;time_base);</span><br><span class="line">        stime2= stime + (<span class="number">1U</span>LL&lt;&lt;ist-&gt;st-&gt;pts_wrap_bits);</span><br><span class="line">        ist-&gt;wrap_correction_done = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span>(stime2 &gt; stime &amp;&amp; pkt.dts != AV_NOPTS_VALUE &amp;&amp; pkt.dts &gt; stime + (<span class="number">1L</span>L&lt;&lt;(ist-&gt;st-&gt;pts_wrap_bits<span class="number">-1</span>))) &#123;</span><br><span class="line">            pkt.dts -= <span class="number">1U</span>LL&lt;&lt;ist-&gt;st-&gt;pts_wrap_bits;</span><br><span class="line">            ist-&gt;wrap_correction_done = <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(stime2 &gt; stime &amp;&amp; pkt.pts != AV_NOPTS_VALUE &amp;&amp; pkt.pts &gt; stime + (<span class="number">1L</span>L&lt;&lt;(ist-&gt;st-&gt;pts_wrap_bits<span class="number">-1</span>))) &#123;</span><br><span class="line">            pkt.pts -= <span class="number">1U</span>LL&lt;&lt;ist-&gt;st-&gt;pts_wrap_bits;</span><br><span class="line">            ist-&gt;wrap_correction_done = <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* add the stream-global side data to the first packet */</span></span><br><span class="line">    <span class="keyword">if</span> (ist-&gt;nb_packets == <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; ist-&gt;st-&gt;nb_side_data; i++) &#123;   <span class="comment">// mp4基本上不会有</span></span><br><span class="line">            AVPacketSideData *src_sd = &amp;ist-&gt;st-&gt;side_data[i];<span class="comment">//side_data：容器提供的一些附加数据</span></span><br><span class="line">            <span class="keyword">uint8_t</span> *dst_data;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (src_sd-&gt;type == AV_PKT_DATA_DISPLAYMATRIX)</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (av_packet_get_side_data(&amp;pkt, src_sd-&gt;type, <span class="literal">NULL</span>))</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line"></span><br><span class="line">            dst_data = av_packet_new_side_data(&amp;pkt, src_sd-&gt;type, src_sd-&gt;size);</span><br><span class="line">            <span class="keyword">if</span> (!dst_data)</span><br><span class="line">                exit_program(<span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">            <span class="built_in">memcpy</span>(dst_data, src_sd-&gt;data, src_sd-&gt;size);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 根据ts_offset调整dts、pts</span></span><br><span class="line">    <span class="keyword">if</span> (pkt.dts != AV_NOPTS_VALUE) &#123;</span><br><span class="line">        pkt.dts += av_rescale_q(ifile-&gt;ts_offset, AV_TIME_BASE_Q, ist-&gt;st-&gt;time_base);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (pkt.pts != AV_NOPTS_VALUE) &#123;</span><br><span class="line">        pkt.pts += av_rescale_q(ifile-&gt;ts_offset, AV_TIME_BASE_Q, ist-&gt;st-&gt;time_base);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 是否需要修改pts、dts各自的等比缩放值</span></span><br><span class="line">    <span class="keyword">if</span> (pkt.pts != AV_NOPTS_VALUE)</span><br><span class="line">        pkt.pts *= ist-&gt;ts_scale;</span><br><span class="line">    <span class="keyword">if</span> (pkt.dts != AV_NOPTS_VALUE)</span><br><span class="line">        pkt.dts *= ist-&gt;ts_scale;</span><br><span class="line">    <span class="comment">// av_rescale_q_rnd a*b/c  转成微妙  AV_ROUND_NEAR_INF 四舍五入</span></span><br><span class="line">    pkt_dts = av_rescale_q_rnd(pkt.dts, ist-&gt;st-&gt;time_base, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);</span><br><span class="line">    <span class="keyword">if</span> ((ist-&gt;dec_ctx-&gt;codec_type == AVMEDIA_TYPE_VIDEO ||</span><br><span class="line">         ist-&gt;dec_ctx-&gt;codec_type == AVMEDIA_TYPE_AUDIO) &amp;&amp;</span><br><span class="line">        pkt_dts != AV_NOPTS_VALUE &amp;&amp; ist-&gt;next_dts == AV_NOPTS_VALUE &amp;&amp; !copy_ts</span><br><span class="line">        &amp;&amp; (is-&gt;iformat-&gt;flags &amp; AVFMT_TS_DISCONT) &amp;&amp; ifile-&gt;last_ts != AV_NOPTS_VALUE) &#123;</span><br><span class="line">        <span class="keyword">int64_t</span> delta   = pkt_dts - ifile-&gt;last_ts; <span class="comment">// 一般情况不会进来</span></span><br><span class="line">        <span class="keyword">if</span> (delta &lt; <span class="number">-1L</span>L*dts_delta_threshold*AV_TIME_BASE ||</span><br><span class="line">            delta &gt;  <span class="number">1L</span>L*dts_delta_threshold*AV_TIME_BASE)&#123;</span><br><span class="line">            ifile-&gt;ts_offset -= delta;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_DEBUG,</span><br><span class="line">                   <span class="string">&quot;Inter stream timestamp discontinuity %&quot;</span>PRId64<span class="string">&quot;, new offset= %&quot;</span>PRId64<span class="string">&quot;\n&quot;</span>,</span><br><span class="line">                   delta, ifile-&gt;ts_offset);</span><br><span class="line">            pkt.dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist-&gt;st-&gt;time_base);</span><br><span class="line">            <span class="keyword">if</span> (pkt.pts != AV_NOPTS_VALUE)</span><br><span class="line">                pkt.pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist-&gt;st-&gt;time_base);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// ifile-&gt;duration 流循环时才有作用，否则为0，循环读取后，pts需要叠加上之前的长度</span></span><br><span class="line">    duration = av_rescale_q(ifile-&gt;duration, ifile-&gt;time_base, ist-&gt;st-&gt;time_base);</span><br><span class="line">    <span class="keyword">if</span> (pkt.pts != AV_NOPTS_VALUE) &#123;</span><br><span class="line">        pkt.pts += duration;</span><br><span class="line">        ist-&gt;max_pts = FFMAX(pkt.pts, ist-&gt;max_pts);    <span class="comment">// 保存最大pts</span></span><br><span class="line">        ist-&gt;min_pts = FFMIN(pkt.pts, ist-&gt;min_pts);    <span class="comment">// 保存最小pts，以备计算duration</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (pkt.dts != AV_NOPTS_VALUE)</span><br><span class="line">        pkt.dts += duration;</span><br><span class="line"></span><br><span class="line">    pkt_dts = av_rescale_q_rnd(pkt.dts, ist-&gt;st-&gt;time_base, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);</span><br><span class="line">    <span class="keyword">if</span> ((ist-&gt;dec_ctx-&gt;codec_type == AVMEDIA_TYPE_VIDEO ||</span><br><span class="line">         ist-&gt;dec_ctx-&gt;codec_type == AVMEDIA_TYPE_AUDIO) &amp;&amp;</span><br><span class="line">         pkt_dts != AV_NOPTS_VALUE &amp;&amp; ist-&gt;next_dts != AV_NOPTS_VALUE &amp;&amp;</span><br><span class="line">        !copy_ts) &#123;     <span class="comment">// 这里一般也不会进来</span></span><br><span class="line">        <span class="keyword">int64_t</span> delta   = pkt_dts - ist-&gt;next_dts;</span><br><span class="line">        <span class="keyword">if</span> (is-&gt;iformat-&gt;flags &amp; AVFMT_TS_DISCONT) &#123;</span><br><span class="line">            <span class="keyword">if</span> (delta &lt; <span class="number">-1L</span>L*dts_delta_threshold*AV_TIME_BASE ||</span><br><span class="line">                delta &gt;  <span class="number">1L</span>L*dts_delta_threshold*AV_TIME_BASE ||</span><br><span class="line">                pkt_dts + AV_TIME_BASE/<span class="number">10</span> &lt; FFMAX(ist-&gt;pts, ist-&gt;dts)) &#123;</span><br><span class="line">                ifile-&gt;ts_offset -= delta;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_DEBUG,</span><br><span class="line">                       <span class="string">&quot;timestamp discontinuity for stream #%d:%d &quot;</span></span><br><span class="line">                       <span class="string">&quot;(id=%d, type=%s): %&quot;</span>PRId64<span class="string">&quot;, new offset= %&quot;</span>PRId64<span class="string">&quot;\n&quot;</span>,</span><br><span class="line">                       ist-&gt;file_index, ist-&gt;st-&gt;index, ist-&gt;st-&gt;id,</span><br><span class="line">                       av_get_media_type_string(ist-&gt;dec_ctx-&gt;codec_type),</span><br><span class="line">                       delta, ifile-&gt;ts_offset);</span><br><span class="line">                pkt.dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist-&gt;st-&gt;time_base);</span><br><span class="line">                <span class="keyword">if</span> (pkt.pts != AV_NOPTS_VALUE)</span><br><span class="line">                    pkt.pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist-&gt;st-&gt;time_base);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> ( delta &lt; <span class="number">-1L</span>L*dts_error_threshold*AV_TIME_BASE ||</span><br><span class="line">                 delta &gt;  <span class="number">1L</span>L*dts_error_threshold*AV_TIME_BASE) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_WARNING, <span class="string">&quot;DTS %&quot;</span>PRId64<span class="string">&quot;, next:%&quot;</span>PRId64<span class="string">&quot; st:%d invalid dropping\n&quot;</span>, pkt.dts, ist-&gt;next_dts, pkt.stream_index);</span><br><span class="line">                pkt.dts = AV_NOPTS_VALUE;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (pkt.pts != AV_NOPTS_VALUE)&#123;</span><br><span class="line">                <span class="keyword">int64_t</span> pkt_pts = av_rescale_q(pkt.pts, ist-&gt;st-&gt;time_base, AV_TIME_BASE_Q);</span><br><span class="line">                delta   = pkt_pts - ist-&gt;next_dts;</span><br><span class="line">                <span class="keyword">if</span> ( delta &lt; <span class="number">-1L</span>L*dts_error_threshold*AV_TIME_BASE ||</span><br><span class="line">                     delta &gt;  <span class="number">1L</span>L*dts_error_threshold*AV_TIME_BASE) &#123;</span><br><span class="line">                    av_log(<span class="literal">NULL</span>, AV_LOG_WARNING, <span class="string">&quot;PTS %&quot;</span>PRId64<span class="string">&quot;, next:%&quot;</span>PRId64<span class="string">&quot; invalid dropping st:%d\n&quot;</span>, pkt.pts, ist-&gt;next_dts, pkt.stream_index);</span><br><span class="line">                    pkt.pts = AV_NOPTS_VALUE;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (pkt.dts != AV_NOPTS_VALUE) &#123;</span><br><span class="line">        <span class="comment">// 记录最近的时间戳，使用微妙</span></span><br><span class="line">        ifile-&gt;last_ts = av_rescale_q(pkt.dts, ist-&gt;st-&gt;time_base, AV_TIME_BASE_Q);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (debug_ts) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;demuxer+ffmpeg -&gt; ist_index:%d type:%s pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s off:%s off_time:%s\n&quot;</span>,</span><br><span class="line">               ifile-&gt;ist_index + pkt.stream_index, av_get_media_type_string(ist-&gt;dec_ctx-&gt;codec_type),</span><br><span class="line">               av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &amp;ist-&gt;st-&gt;time_base),</span><br><span class="line">               av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &amp;ist-&gt;st-&gt;time_base),</span><br><span class="line">               av_ts2str(input_files[ist-&gt;file_index]-&gt;ts_offset),</span><br><span class="line">               av_ts2timestr(input_files[ist-&gt;file_index]-&gt;ts_offset, &amp;AV_TIME_BASE_Q));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    process_input_packet(ist, &amp;pkt, <span class="number">0</span>); <span class="comment">// 到这里pts dts实际上还是AVStream的time_base</span></span><br><span class="line"></span><br><span class="line">discard_packet:</span><br><span class="line">    av_packet_unref(&amp;pkt);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Perform a step of transcoding for the specified filter graph.</span></span><br><span class="line"><span class="comment"> * 根据输出流选择所需的输入流，ffmpeg选择输入流的规则是当前缓冲区中没有数据的，</span></span><br><span class="line"><span class="comment"> * 迫切需要获取的，选择出来的是输入流下标 ，比如两路流 选择的是0 或1</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * @param[in]  graph     filter graph to consider</span></span><br><span class="line"><span class="comment"> * @param[out] best_ist  input stream where a frame would allow to continue</span></span><br><span class="line"><span class="comment"> * @return  0 for success, &lt;0 for error</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">transcode_from_filter</span><span class="params">(FilterGraph *graph, InputStream **best_ist)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i, ret;</span><br><span class="line">    <span class="keyword">int</span> nb_requests, nb_requests_max = <span class="number">0</span>;</span><br><span class="line">    InputFilter *ifilter;</span><br><span class="line">    InputStream *ist;</span><br><span class="line"></span><br><span class="line">    *best_ist = <span class="literal">NULL</span>;</span><br><span class="line">    ret = avfilter_graph_request_oldest(graph-&gt;graph);</span><br><span class="line">    <span class="keyword">if</span> (ret &gt;= <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">return</span> reap_filters(<span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ret == AVERROR_EOF) &#123;</span><br><span class="line">        ret = reap_filters(<span class="number">1</span>);</span><br><span class="line">        <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; graph-&gt;nb_outputs; i++)</span><br><span class="line">            close_output_stream(graph-&gt;outputs[i]-&gt;ost);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (ret != AVERROR(EAGAIN))</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; graph-&gt;nb_inputs; i++) &#123;</span><br><span class="line">        ifilter = graph-&gt;inputs[i];</span><br><span class="line">        ist = ifilter-&gt;ist;</span><br><span class="line">        <span class="keyword">if</span> (input_files[ist-&gt;file_index]-&gt;eagain ||</span><br><span class="line">            input_files[ist-&gt;file_index]-&gt;eof_reached)</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        nb_requests = av_buffersrc_get_nb_failed_requests(ifilter-&gt;filter);</span><br><span class="line">        <span class="keyword">if</span> (nb_requests &gt; nb_requests_max) &#123;</span><br><span class="line">            nb_requests_max = nb_requests;</span><br><span class="line">            *best_ist = ist;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!*best_ist)</span><br><span class="line">        <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; graph-&gt;nb_outputs; i++)</span><br><span class="line">            graph-&gt;outputs[i]-&gt;ost-&gt;unavailable = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Run a single step of transcoding.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * @return  0 for success, &lt;0 for error</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">transcode_step</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    OutputStream *ost;</span><br><span class="line">    InputStream  *ist = <span class="literal">NULL</span>;</span><br><span class="line">    <span class="keyword">int</span> ret;</span><br><span class="line">    <span class="comment">// 选择时间戳最小的流，以便一直循环遍历</span></span><br><span class="line">    ost = choose_output();  <span class="comment">// 问题是选出来OutputStream后，av_read_frame的时候并不一定是它对应的流</span></span><br><span class="line">    <span class="keyword">if</span> (!ost) &#123;</span><br><span class="line">        <span class="keyword">if</span> (got_eagain()) &#123;</span><br><span class="line">            reset_eagain();</span><br><span class="line">            av_usleep(<span class="number">10000</span>);</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;No more inputs to read from, finishing.\n&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> AVERROR_EOF;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ost-&gt;filter &amp;&amp; !ost-&gt;filter-&gt;graph-&gt;graph) &#123;</span><br><span class="line">        <span class="keyword">if</span> (ifilter_has_all_input_formats(ost-&gt;filter-&gt;graph)) &#123;    <span class="comment">// 这里检测的意义</span></span><br><span class="line">            ret = configure_filtergraph(ost-&gt;filter-&gt;graph);    <span class="comment">// 包括构建graph</span></span><br><span class="line">            <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;Error reinitializing filters!\n&quot;</span>);</span><br><span class="line">                <span class="keyword">return</span> ret;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ost-&gt;filter &amp;&amp; ost-&gt;filter-&gt;graph-&gt;graph) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!ost-&gt;initialized) &#123;</span><br><span class="line">            <span class="keyword">char</span> error[<span class="number">1024</span>] = &#123;<span class="number">0</span>&#125;;</span><br><span class="line">            ret = init_output_stream(ost, error, <span class="keyword">sizeof</span>(error));</span><br><span class="line">            <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;Error initializing output stream %d:%d -- %s\n&quot;</span>,</span><br><span class="line">                       ost-&gt;file_index, ost-&gt;index, error);</span><br><span class="line">                exit_program(<span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> ((ret = transcode_from_filter(ost-&gt;filter-&gt;graph, &amp;ist)) &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> ret;</span><br><span class="line">        <span class="keyword">if</span> (!ist)</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (ost-&gt;filter) &#123;</span><br><span class="line">        <span class="keyword">int</span> i;</span><br><span class="line">        <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; ost-&gt;filter-&gt;graph-&gt;nb_inputs; i++) &#123;</span><br><span class="line">            InputFilter *ifilter = ost-&gt;filter-&gt;graph-&gt;inputs[i];</span><br><span class="line">            <span class="keyword">if</span> (!ifilter-&gt;ist-&gt;got_output &amp;&amp; !input_files[ifilter-&gt;ist-&gt;file_index]-&gt;eof_reached) &#123;</span><br><span class="line">                ist = ifilter-&gt;ist;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (!ist) &#123;</span><br><span class="line">            ost-&gt;inputs_done = <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        av_assert0(ost-&gt;source_index &gt;= <span class="number">0</span>);</span><br><span class="line">        ist = input_streams[ost-&gt;source_index];</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    ret = process_input(ist-&gt;file_index);       <span class="comment">// 只管到读包和解码</span></span><br><span class="line">    <span class="keyword">if</span> (ret == AVERROR(EAGAIN)) &#123;</span><br><span class="line">        <span class="keyword">if</span> (input_files[ist-&gt;file_index]-&gt;eagain)</span><br><span class="line">            ost-&gt;unavailable = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">return</span> ret == AVERROR_EOF ? <span class="number">0</span> : ret;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> reap_filters(<span class="number">0</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * The following code is the main loop of the file converter</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">transcode</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> ret, i;</span><br><span class="line">    AVFormatContext *os;</span><br><span class="line">    OutputStream *ost;</span><br><span class="line">    InputStream *ist;</span><br><span class="line">    <span class="keyword">int64_t</span> timer_start;</span><br><span class="line">    <span class="keyword">int64_t</span> total_packets_written = <span class="number">0</span>;</span><br><span class="line">    <span class="comment">// 初始化，打开所有输出流的编码器,打开所有输入流的解码器,写入所有输出文件的文件头</span></span><br><span class="line">    ret = transcode_init();</span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">goto</span> fail;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (stdin_interaction) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;Press [q] to stop, [?] for help\n&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    timer_start = av_gettime_relative();</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_THREADS</span></span><br><span class="line">    <span class="keyword">if</span> ((ret = init_input_threads()) &lt; <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">goto</span> fail;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line">    <span class="comment">// 循环,直到收到系统信号才退出 。</span></span><br><span class="line">    <span class="keyword">while</span> (!received_sigterm) &#123;</span><br><span class="line">        <span class="keyword">int64_t</span> cur_time= av_gettime_relative();</span><br><span class="line"></span><br><span class="line">        <span class="comment">/* if &#x27;q&#x27; pressed, exits */</span></span><br><span class="line">        <span class="keyword">if</span> (stdin_interaction)</span><br><span class="line">            <span class="keyword">if</span> (check_keyboard_interaction(cur_time) &lt; <span class="number">0</span>)       <span class="comment">// 按键事件的响应</span></span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/* check if there&#x27;s any stream where output is still needed */</span></span><br><span class="line">        <span class="keyword">if</span> (!need_output()) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_VERBOSE, <span class="string">&quot;No more output streams to write to, finishing.\n&quot;</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 具体的转换工作</span></span><br><span class="line">        ret = transcode_step();</span><br><span class="line">        <span class="keyword">if</span> (ret &lt; <span class="number">0</span> &amp;&amp; ret != AVERROR_EOF) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;Error while filtering: %s\n&quot;</span>, av_err2str(ret));</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/* dump report by using the output first video and audio streams */</span></span><br><span class="line">        print_report(<span class="number">0</span>, timer_start, cur_time);</span><br><span class="line">    &#125;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_THREADS</span></span><br><span class="line">    free_input_threads();</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line">    <span class="comment">// 文件处理完了,把缓冲中剩余的数据写到输出文件中</span></span><br><span class="line">    <span class="comment">/* at the end of stream, we must flush the decoder buffers */</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_input_streams; i++) &#123;</span><br><span class="line">        ist = input_streams[i];</span><br><span class="line">        <span class="keyword">if</span> (!input_files[ist-&gt;file_index]-&gt;eof_reached) &#123; <span class="comment">// 如果没有读取完毕</span></span><br><span class="line">            process_input_packet(ist, <span class="literal">NULL</span>, <span class="number">0</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    flush_encoders();</span><br><span class="line"></span><br><span class="line">    term_exit();</span><br><span class="line">    <span class="comment">// 为输出文件写文件尾(有的不需要)。</span></span><br><span class="line">    <span class="comment">/* write the trailer if needed and close file */</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_files; i++) &#123;</span><br><span class="line">        os = output_files[i]-&gt;ctx;</span><br><span class="line">        <span class="keyword">if</span> (!output_files[i]-&gt;header_written) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_ERROR,</span><br><span class="line">                   <span class="string">&quot;Nothing was written into output file %d (%s), because &quot;</span></span><br><span class="line">                   <span class="string">&quot;at least one of its streams received no packets.\n&quot;</span>,</span><br><span class="line">                   i, os-&gt;url);</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> ((ret = av_write_trailer(os)) &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            av_log(<span class="literal">NULL</span>, AV_LOG_ERROR, <span class="string">&quot;Error writing trailer of %s: %s\n&quot;</span>, os-&gt;url, av_err2str(ret));</span><br><span class="line">            <span class="keyword">if</span> (exit_on_error)</span><br><span class="line">                exit_program(<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* dump report by using the first video and audio streams */</span></span><br><span class="line">    print_report(<span class="number">1</span>, timer_start, av_gettime_relative());</span><br><span class="line">     <span class="comment">// 关闭所有解码器</span></span><br><span class="line">    <span class="comment">/* close each encoder */</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_streams; i++) &#123;</span><br><span class="line">        ost = output_streams[i];</span><br><span class="line">        <span class="keyword">if</span> (ost-&gt;encoding_needed) &#123;</span><br><span class="line">            av_freep(&amp;ost-&gt;enc_ctx-&gt;stats_in);</span><br><span class="line">        &#125;</span><br><span class="line">        total_packets_written += ost-&gt;packets_written;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!total_packets_written &amp;&amp; (abort_on_flags &amp; ABORT_ON_FLAG_EMPTY_OUTPUT)) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_FATAL, <span class="string">&quot;Empty output\n&quot;</span>);</span><br><span class="line">        exit_program(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 关闭所有解码器</span></span><br><span class="line">    <span class="comment">/* close each decoder */</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_input_streams; i++) &#123;</span><br><span class="line">        ist = input_streams[i];</span><br><span class="line">        <span class="keyword">if</span> (ist-&gt;decoding_needed) &#123;</span><br><span class="line">            avcodec_close(ist-&gt;dec_ctx);</span><br><span class="line">            <span class="keyword">if</span> (ist-&gt;hwaccel_uninit)</span><br><span class="line">                ist-&gt;hwaccel_uninit(ist-&gt;dec_ctx);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    av_buffer_unref(&amp;hw_device_ctx);</span><br><span class="line">    hw_device_free_all();</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* finished ! */</span></span><br><span class="line">    ret = <span class="number">0</span>;</span><br><span class="line">    av_log(<span class="literal">NULL</span>, AV_LOG_INFO, <span class="string">&quot;Finish\n&quot;</span>);</span><br><span class="line"> fail:</span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_THREADS</span></span><br><span class="line">    free_input_threads();</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (output_streams) &#123;</span><br><span class="line">        <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_streams; i++) &#123;</span><br><span class="line">            ost = output_streams[i];</span><br><span class="line">            <span class="keyword">if</span> (ost) &#123;</span><br><span class="line">                <span class="keyword">if</span> (ost-&gt;logfile) &#123;</span><br><span class="line">                    <span class="keyword">if</span> (fclose(ost-&gt;logfile))</span><br><span class="line">                        av_log(<span class="literal">NULL</span>, AV_LOG_ERROR,</span><br><span class="line">                               <span class="string">&quot;Error closing logfile, loss of information possible: %s\n&quot;</span>,</span><br><span class="line">                               av_err2str(AVERROR(errno)));</span><br><span class="line">                    ost-&gt;logfile = <span class="literal">NULL</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                av_freep(&amp;ost-&gt;forced_kf_pts);</span><br><span class="line">                av_freep(&amp;ost-&gt;apad);</span><br><span class="line">                av_freep(&amp;ost-&gt;disposition);</span><br><span class="line">                av_dict_free(&amp;ost-&gt;encoder_opts);</span><br><span class="line">                av_dict_free(&amp;ost-&gt;sws_dict);</span><br><span class="line">                av_dict_free(&amp;ost-&gt;swr_opts);</span><br><span class="line">                av_dict_free(&amp;ost-&gt;resample_opts);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> ret;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> BenchmarkTimeStamps <span class="title">get_benchmark_time_stamps</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    BenchmarkTimeStamps time_stamps = &#123; av_gettime_relative() &#125;;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_GETRUSAGE</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">rusage</span> <span class="title">rusage</span>;</span></span><br><span class="line"></span><br><span class="line">    getrusage(RUSAGE_SELF, &amp;rusage);</span><br><span class="line">    time_stamps.user_usec =</span><br><span class="line">        (rusage.ru_utime.tv_sec * <span class="number">1000000L</span>L) + rusage.ru_utime.tv_usec;</span><br><span class="line">    time_stamps.sys_usec =</span><br><span class="line">        (rusage.ru_stime.tv_sec * <span class="number">1000000L</span>L) + rusage.ru_stime.tv_usec;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">elif</span> HAVE_GETPROCESSTIMES</span></span><br><span class="line">    HANDLE proc;</span><br><span class="line">    FILETIME c, e, k, u;</span><br><span class="line">    proc = GetCurrentProcess();</span><br><span class="line">    GetProcessTimes(proc, &amp;c, &amp;e, &amp;k, &amp;u);</span><br><span class="line">    time_stamps.user_usec =</span><br><span class="line">        ((<span class="keyword">int64_t</span>)u.dwHighDateTime &lt;&lt; <span class="number">32</span> | u.dwLowDateTime) / <span class="number">10</span>;</span><br><span class="line">    time_stamps.sys_usec =</span><br><span class="line">        ((<span class="keyword">int64_t</span>)k.dwHighDateTime &lt;&lt; <span class="number">32</span> | k.dwLowDateTime) / <span class="number">10</span>;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">else</span></span></span><br><span class="line">    time_stamps.user_usec = time_stamps.sys_usec = <span class="number">0</span>;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line">    <span class="keyword">return</span> time_stamps;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int64_t</span> <span class="title">getmaxrss</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> HAVE_GETRUSAGE &amp;&amp; HAVE_STRUCT_RUSAGE_RU_MAXRSS</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">rusage</span> <span class="title">rusage</span>;</span></span><br><span class="line">    getrusage(RUSAGE_SELF, &amp;rusage);</span><br><span class="line">    <span class="keyword">return</span> (<span class="keyword">int64_t</span>)rusage.ru_maxrss * <span class="number">1024</span>;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">elif</span> HAVE_GETPROCESSMEMORYINFO</span></span><br><span class="line">    HANDLE proc;</span><br><span class="line">    PROCESS_MEMORY_COUNTERS memcounters;</span><br><span class="line">    proc = GetCurrentProcess();</span><br><span class="line">    memcounters.cb = <span class="keyword">sizeof</span>(memcounters);</span><br><span class="line">    GetProcessMemoryInfo(proc, &amp;memcounters, <span class="keyword">sizeof</span>(memcounters));</span><br><span class="line">    <span class="keyword">return</span> memcounters.PeakPagefileUsage;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">else</span></span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">log_callback_null</span><span class="params">(<span class="keyword">void</span> *ptr, <span class="keyword">int</span> level, <span class="keyword">const</span> <span class="keyword">char</span> *fmt, va_list vl)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> **argv)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i, ret;</span><br><span class="line">    BenchmarkTimeStamps ti;</span><br><span class="line"></span><br><span class="line">    init_dynload();</span><br><span class="line"></span><br><span class="line">    register_exit(ffmpeg_cleanup);</span><br><span class="line"></span><br><span class="line">    setvbuf(<span class="built_in">stderr</span>,<span class="literal">NULL</span>,_IONBF,<span class="number">0</span>); <span class="comment">/* win32 runtime needs this */</span></span><br><span class="line"></span><br><span class="line">    av_log_set_flags(AV_LOG_SKIP_REPEATED);</span><br><span class="line">    parse_loglevel(argc, argv, options);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(argc&gt;<span class="number">1</span> &amp;&amp; !<span class="built_in">strcmp</span>(argv[<span class="number">1</span>], <span class="string">&quot;-d&quot;</span>))&#123;</span><br><span class="line">        run_as_daemon=<span class="number">1</span>;</span><br><span class="line">        av_log_set_callback(log_callback_null);</span><br><span class="line">        argc--;</span><br><span class="line">        argv++;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> CONFIG_AVDEVICE</span></span><br><span class="line">    avdevice_register_all();</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line">    avformat_network_init();</span><br><span class="line"></span><br><span class="line">    show_banner(argc, argv, options);</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* parse options and open all input/output files */</span></span><br><span class="line">    ret = ffmpeg_parse_options(argc, argv);<span class="comment">//解析输入命令</span></span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>)</span><br><span class="line">        exit_program(<span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (nb_output_files &lt;= <span class="number">0</span> &amp;&amp; nb_input_files == <span class="number">0</span>) &#123;</span><br><span class="line">        show_usage();</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_WARNING, <span class="string">&quot;Use -h to get full help or, even better, run &#x27;man %s&#x27;\n&quot;</span>, program_name);</span><br><span class="line">        exit_program(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* file converter / grab */</span></span><br><span class="line">    <span class="keyword">if</span> (nb_output_files &lt;= <span class="number">0</span>) &#123;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_FATAL, <span class="string">&quot;At least one output file must be specified\n&quot;</span>);</span><br><span class="line">        exit_program(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nb_output_files; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="built_in">strcmp</span>(output_files[i]-&gt;ctx-&gt;oformat-&gt;name, <span class="string">&quot;rtp&quot;</span>))</span><br><span class="line">            want_sdp = <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    current_time = ti = get_benchmark_time_stamps();</span><br><span class="line">    <span class="keyword">if</span> (transcode() &lt; <span class="number">0</span>)       <span class="comment">// ffmpeg运行起来后</span></span><br><span class="line">        exit_program(<span class="number">1</span>);</span><br><span class="line">    <span class="keyword">if</span> (do_benchmark) &#123;</span><br><span class="line">        <span class="keyword">int64_t</span> utime, stime, rtime;</span><br><span class="line">        current_time = get_benchmark_time_stamps();</span><br><span class="line">        utime = current_time.user_usec - ti.user_usec;</span><br><span class="line">        stime = current_time.sys_usec  - ti.sys_usec;</span><br><span class="line">        rtime = current_time.real_usec - ti.real_usec;</span><br><span class="line">        av_log(<span class="literal">NULL</span>, AV_LOG_INFO,</span><br><span class="line">               <span class="string">&quot;bench: utime=%0.3fs stime=%0.3fs rtime=%0.3fs\n&quot;</span>,</span><br><span class="line">               utime / <span class="number">1000000.0</span>, stime / <span class="number">1000000.0</span>, rtime / <span class="number">1000000.0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    av_log(<span class="literal">NULL</span>, AV_LOG_DEBUG, <span class="string">&quot;%&quot;</span>PRIu64<span class="string">&quot; frames successfully decoded, %&quot;</span>PRIu64<span class="string">&quot; decoding errors\n&quot;</span>,</span><br><span class="line">           decode_error_stat[<span class="number">0</span>], decode_error_stat[<span class="number">1</span>]);</span><br><span class="line">    <span class="keyword">if</span> ((decode_error_stat[<span class="number">0</span>] + decode_error_stat[<span class="number">1</span>]) * max_error_rate &lt; decode_error_stat[<span class="number">1</span>])</span><br><span class="line">        exit_program(<span class="number">69</span>);</span><br><span class="line"></span><br><span class="line">    exit_program(received_nb_signals ? <span class="number">255</span> : main_return_code);</span><br><span class="line">    <span class="keyword">return</span> main_return_code;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


    

    
    <div class="page-reward">
      <a href="javascript:void(0);" class="page-reward-btn tooltip-top" target="_self">
        <div class="tooltip tooltip-east">
          <span class="tooltip-item">
            赏
          </span>
          <span class="tooltip-content">
            <span class="tooltip-text">
              <span class="tooltip-inner">
                <p class="reward-p"><i class="icon icon-quo-left"></i>谢谢你请我吃糖果<i
                    class="icon icon-quo-right"></i></p>
                <div class="reward-box">
                  
                  <div class="reward-box-item">
                    <img class="reward-img" src="/blog/img/alipay.jpg">
                    <span class="reward-type">支付宝</span>
                  </div>
                  
                  
                  <div class="reward-box-item">
                    <img class="reward-img" src="/blog/img/weixin.png">
                    <span class="reward-type">微信</span>
                  </div>
                  
                </div>
              </span>
            </span>
          </span>
        </div>
      </a>
    </div>
    

    
    <div class="declare"> 
      <ul class="post-copyright">
        <li>
          <strong>本文作者：</strong>
          Moses Yu
        </li>
        <li>
          <strong>本文链接：</strong>
          <a href="http://example.com/blog/2021/08/10/监控开发/视频监控系统 FFmpeg方案/" title="视频监控系统 FFmpeg方案" target="_blank">http://example.com/blog/2021/08/10/监控开发/视频监控系统 FFmpeg方案/</a>
        </li>
        
        <li>
          <strong>版权声明： </strong>
          
          本博客所有文章除特别声明外，均采用 <a href="https://github.com/JoeyBling/hexo-theme-yilia-plus/blob/master/LICENSE" rel="external nofollow" target="_blank">MIT</a> 许可协议。转载请注明出处！
        </li>
        
      </ul>
    </div>
    

  </div>
  <div class="article-info article-info-index">
    
    
	<div class="article-tag tagcloud">
		<i class="icon-price-tags icon"></i>
		<ul class="article-tag-list">
			 
        		<li class="article-tag-list-item">
        			<a href="javascript:void(0)" class="js-tag article-tag-list-link color2">视频监控系统</a>
        		</li>
      		
		</ul>
	</div>

    
	<div class="article-category tagcloud">
		<i class="icon-book icon"></i>
		<ul class="article-tag-list">
			 
        		<li class="article-tag-list-item">
        			<a href="/blog/categories/项目实验//" class="article-tag-list-link color5">项目实验</a>
        		</li>
      		
		</ul>
	</div>


    

    
    
<div class="share-btn share-icons tooltip-left">
  <div class="tooltip tooltip-east">
    <span class="tooltip-item">
      <a href="javascript:;" class="share-sns share-outer">
        <i class="icon icon-share"></i>
      </a>
    </span>
    <span class="tooltip-content">
      <div class="share-wrap">
        <div class="share-icons">
          <a class="weibo share-sns" href="javascript:;" data-type="weibo">
            <i class="icon icon-weibo"></i>
          </a>
          <!-- <a class="weixin share-sns wxFab" href="javascript:;" data-type="weixin">
            <i class="icon icon-weixin"></i>
          </a> -->
          <a class="qq share-sns" href="javascript:;" data-type="qq">
            <i class="icon icon-qq"></i>
          </a>
          <a class="douban share-sns" href="javascript:;" data-type="douban">
            <i class="icon icon-douban"></i>
          </a>
          <a class="qzone share-sns" href="javascript:;" data-type="qzone">
            <i class="icon icon-qzone"></i>
          </a>
          <a class="facebook share-sns" href="javascript:;" data-type="facebook">
            <i class="icon icon-facebook"></i>
          </a>
          <a class="twitter share-sns" href="javascript:;" data-type="twitter">
            <i class="icon icon-twitter"></i>
          </a>
          <a class="google share-sns" href="javascript:;" data-type="google">
            <i class="icon icon-google"></i>
          </a>
        </div>
      </div>
    </span>
  </div>
</div>

<div class="page-modal wx-share js-wx-box">
    <a class="close js-modal-close" href="javascript:;"><i class="icon icon-close"></i></a>
    <p>扫一扫，分享到微信</p>
    <div class="wx-qrcode">
     <!-- <img src="//pan.baidu.com/share/qrcode?url=http://example.com/2021/08/10/%E7%9B%91%E6%8E%A7%E5%BC%80%E5%8F%91/%E8%A7%86%E9%A2%91%E7%9B%91%E6%8E%A7%E7%B3%BB%E7%BB%9F%20FFmpeg%E6%96%B9%E6%A1%88/" alt="微信分享二维码"> -->
    </div>
</div>

<div class="mask js-mask"></div>

    
    <div class="clearfix"></div>
  </div>
  </div>
</article>


<nav id="article-nav">
  
    <a href="/blog/2021/12/19/Linux%20%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%93%E5%BC%80%E5%8F%91/libconfig%E5%BA%93%E5%BC%80%E5%8F%91/" id="article-nav-newer" class="article-nav-link-wrap">
      <i class="icon-circle-left"></i>
      <div class="article-nav-title">
        
          libconfig库开发
        
      </div>
    </a>
  
  
    <a href="/blog/2021/08/09/%E7%9B%91%E6%8E%A7%E5%BC%80%E5%8F%91/%E8%A7%86%E9%A2%91%E7%9B%91%E6%8E%A7%E7%B3%BB%E7%BB%9F%20mjpg-streamer%E6%96%B9%E6%A1%88/" id="article-nav-older" class="article-nav-link-wrap">
      <div class="article-nav-title">视频监控系统 mjpg-streamer方案</div>
      <i class="icon-circle-right"></i>
    </a>
  
</nav>


<aside class="wrap-side-operation">
    <div class="mod-side-operation">
        
        <div class="jump-container" id="js-jump-container" style="display:none;">
            <a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
                <i class="icon-font icon-back"></i>
            </a>
            <div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
                <i class="icon-font icon-plane jump-plane"></i>
            </div>
        </div>
        
        
    </div>
</aside>














          </div>
        </div>
      </div>
      <footer id="footer">
  <div class="outer">
    <div id="footer-info">
    	<div class="footer-left">
    		&copy; 2020-2021 <a href="http://example.com/blog/" target="_blank">Moses Yu</a>
    	</div>
      	<div class="footer-right">
			
			
      		GitHub:<a href="https://github.com/JoeyBling/hexo-theme-yilia-plus" target="_blank">hexo-theme-yilia-plus</a> by Litten
      	</div>
    </div>
  </div>
  
  
	<script src="/blog/lib/busuanzi.pure.js"></script>
	
  
  
	
	<span id="busuanzi_container_site_pv" style="display:none">
		本站总访问量<span id="busuanzi_value_site_pv"></span>次	
	        <span class="post-meta-divider" >|</span>
	</span>
  	<span id="busuanzi_container_site_uv" style='display:none'>
  		本站访客数<span id="busuanzi_value_site_uv"></span>人
  	</span>
  
</footer>

    </div>
    <script>
	var yiliaConfig = {
		mathjax: false,
		isHome: false,
		isPost: true,
		isArchive: false,
		isTag: false,
		isCategory: false,
		open_in_new: true,
		toc_hide_index: true,
		root: "/blog/",
		innerArchive: true,
		showTags: true
	}
</script>

<script>!function(r){function e(t){if(i[t])return i[t].exports;var n=i[t]={exports:{},id:t,loaded:!1};return r[t].call(n.exports,n,n.exports,e),n.loaded=!0,n.exports}var i={};e.m=r,e.c=i,e.p="./",e(0)}([function(t,n,r){r(208),t.exports=r(205)},function(t,n,r){var d=r(3),y=r(46),g=r(26),b=r(27),x=r(47),m="prototype",S=function(t,n,r){var e,i,o,u,c=t&S.F,f=t&S.G,a=t&S.S,s=t&S.P,l=t&S.B,h=f?d:a?d[n]||(d[n]={}):(d[n]||{})[m],v=f?y:y[n]||(y[n]={}),p=v[m]||(v[m]={});for(e in f&&(r=n),r)o=((i=!c&&h&&void 0!==h[e])?h:r)[e],u=l&&i?x(o,d):s&&"function"==typeof o?x(Function.call,o):o,h&&b(h,e,o,t&S.U),v[e]!=o&&g(v,e,u),s&&p[e]!=o&&(p[e]=o)};d.core=y,S.F=1,S.G=2,S.S=4,S.P=8,S.B=16,S.W=32,S.U=64,S.R=128,t.exports=S},function(t,n,r){var e=r(5);t.exports=function(t){if(!e(t))throw TypeError(t+" is not an object!");return t}},function(t,n){var r=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=r)},function(t,n){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,n){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,n){var r=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=r)},function(t,n,r){var e=r(118)("wks"),i=r(79),o=r(3).Symbol,u="function"==typeof o;(t.exports=function(t){return e[t]||(e[t]=u&&o[t]||(u?o:i)("Symbol."+t))}).store=e},function(t,n,r){var e=r(49),i=Math.min;t.exports=function(t){return 0<t?i(e(t),9007199254740991):0}},function(t,n){var r={}.hasOwnProperty;t.exports=function(t,n){return r.call(t,n)}},function(t,n,r){t.exports=!r(4)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,n,r){var e=r(2),i=r(174),o=r(53),u=Object.defineProperty;n.f=r(10)?Object.defineProperty:function(t,n,r){if(e(t),n=o(n,!0),e(r),i)try{return u(t,n,r)}catch(t){}if("get"in r||"set"in r)throw TypeError("Accessors not supported!");return"value"in r&&(t[n]=r.value),t}},function(t,n,r){t.exports=!r(20)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,n,r){var e=r(14),i=r(24);t.exports=r(12)?function(t,n,r){return e.f(t,n,i(1,r))}:function(t,n,r){return t[n]=r,t}},function(t,n,r){var e=r(22),i=r(60),o=r(42),u=Object.defineProperty;n.f=r(12)?Object.defineProperty:function(t,n,r){if(e(t),n=o(n,!0),e(r),i)try{return u(t,n,r)}catch(t){}if("get"in r||"set"in r)throw TypeError("Accessors not supported!");return"value"in r&&(t[n]=r.value),t}},function(t,n,r){var e=r(96),i=r(34);t.exports=function(t){return e(i(t))}},function(t,n,r){var e=r(40)("wks"),i=r(25),o=r(6).Symbol,u="function"==typeof o;(t.exports=function(t){return e[t]||(e[t]=u&&o[t]||(u?o:i)("Symbol."+t))}).store=e},function(t,n,r){var e=r(51);t.exports=function(t){return Object(e(t))}},function(t,n){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,n){var r=t.exports={version:"2.6.9"};"number"==typeof __e&&(__e=r)},function(t,n){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,n){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,n,r){var e=r(18);t.exports=function(t){if(!e(t))throw TypeError(t+" is not an object!");return t}},function(t,n){t.exports=!0},function(t,n){t.exports=function(t,n){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:n}}},function(t,n){var r=0,e=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++r+e).toString(36))}},function(t,n,r){var e=r(11),i=r(75);t.exports=r(10)?function(t,n,r){return e.f(t,n,i(1,r))}:function(t,n,r){return t[n]=r,t}},function(t,n,r){var o=r(3),u=r(26),c=r(30),f=r(79)("src"),e=r(219),i="toString",a=(""+e).split(i);r(46).inspectSource=function(t){return e.call(t)},(t.exports=function(t,n,r,e){var i="function"==typeof r;i&&(c(r,"name")||u(r,"name",n)),t[n]!==r&&(i&&(c(r,f)||u(r,f,t[n]?""+t[n]:a.join(String(n)))),t===o?t[n]=r:e?t[n]?t[n]=r:u(t,n,r):(delete t[n],u(t,n,r)))})(Function.prototype,i,function(){return"function"==typeof this&&this[f]||e.call(this)})},function(t,n,r){var e=r(1),i=r(4),u=r(51),c=/"/g,o=function(t,n,r,e){var i=String(u(t)),o="<"+n;return""!==r&&(o+=" "+r+'="'+String(e).replace(c,"&quot;")+'"'),o+">"+i+"</"+n+">"};t.exports=function(n,t){var r={};r[n]=t(o),e(e.P+e.F*i(function(){var t=""[n]('"');return t!==t.toLowerCase()||3<t.split('"').length}),"String",r)}},function(t,n,r){var e=r(65),i=r(35);t.exports=Object.keys||function(t){return e(t,i)}},function(t,n){var r={}.hasOwnProperty;t.exports=function(t,n){return r.call(t,n)}},function(t,n,r){var e=r(117),i=r(75),o=r(33),u=r(53),c=r(30),f=r(174),a=Object.getOwnPropertyDescriptor;n.f=r(10)?a:function(t,n){if(t=o(t),n=u(n,!0),f)try{return a(t,n)}catch(t){}if(c(t,n))return i(!e.f.call(t,n),t[n])}},function(t,n,r){var e=r(30),i=r(17),o=r(154)("IE_PROTO"),u=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=i(t),e(t,o)?t[o]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?u:null}},function(t,n,r){var e=r(116),i=r(51);t.exports=function(t){return e(i(t))}},function(t,n){t.exports=function(t){if(null==t)throw TypeError("Can't call method on  "+t);return t}},function(t,n){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,n){t.exports={}},function(t,n){n.f={}.propertyIsEnumerable},function(t,n,r){var e=r(14).f,i=r(9),o=r(16)("toStringTag");t.exports=function(t,n,r){t&&!i(t=r?t:t.prototype,o)&&e(t,o,{configurable:!0,value:n})}},function(t,n,r){var e=r(40)("keys"),i=r(25);t.exports=function(t){return e[t]||(e[t]=i(t))}},function(t,n,r){var e=r(19),i=r(6),o="__core-js_shared__",u=i[o]||(i[o]={});(t.exports=function(t,n){return u[t]||(u[t]=void 0!==n?n:{})})("versions",[]).push({version:e.version,mode:r(23)?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},function(t,n){var r=Math.ceil,e=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(0<t?e:r)(t)}},function(t,n,r){var i=r(18);t.exports=function(t,n){if(!i(t))return t;var r,e;if(n&&"function"==typeof(r=t.toString)&&!i(e=r.call(t)))return e;if("function"==typeof(r=t.valueOf)&&!i(e=r.call(t)))return e;if(!n&&"function"==typeof(r=t.toString)&&!i(e=r.call(t)))return e;throw TypeError("Can't convert object to primitive value")}},function(t,n,r){var e=r(6),i=r(19),o=r(23),u=r(44),c=r(14).f;t.exports=function(t){var n=i.Symbol||(i.Symbol=o?{}:e.Symbol||{});"_"==t.charAt(0)||t in n||c(n,t,{value:u.f(t)})}},function(t,n,r){n.f=r(16)},function(t,n){var r={}.toString;t.exports=function(t){return r.call(t).slice(8,-1)}},function(t,n){var r=t.exports={version:"2.6.9"};"number"==typeof __e&&(__e=r)},function(t,n,r){var o=r(21);t.exports=function(e,i,t){if(o(e),void 0===i)return e;switch(t){case 1:return function(t){return e.call(i,t)};case 2:return function(t,n){return e.call(i,t,n)};case 3:return function(t,n,r){return e.call(i,t,n,r)}}return function(){return e.apply(i,arguments)}}},function(t,n,r){"use strict";var e=r(4);t.exports=function(t,n){return!!t&&e(function(){n?t.call(null,function(){},1):t.call(null)})}},function(t,n){var r=Math.ceil,e=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(0<t?e:r)(t)}},function(t,n,r){var x=r(47),m=r(116),S=r(17),w=r(8),e=r(138);t.exports=function(l,t){var h=1==l,v=2==l,p=3==l,d=4==l,y=6==l,g=5==l||y,b=t||e;return function(t,n,r){for(var e,i,o=S(t),u=m(o),c=x(n,r,3),f=w(u.length),a=0,s=h?b(t,f):v?b(t,0):void 0;a<f;a++)if((g||a in u)&&(i=c(e=u[a],a,o),l))if(h)s[a]=i;else if(i)switch(l){case 3:return!0;case 5:return e;case 6:return a;case 2:s.push(e)}else if(d)return!1;return y?-1:p||d?d:s}}},function(t,n){t.exports=function(t){if(null==t)throw TypeError("Can't call method on  "+t);return t}},function(t,n,r){var i=r(1),o=r(46),u=r(4);t.exports=function(t,n){var r=(o.Object||{})[t]||Object[t],e={};e[t]=n(r),i(i.S+i.F*u(function(){r(1)}),"Object",e)}},function(t,n,r){var i=r(5);t.exports=function(t,n){if(!i(t))return t;var r,e;if(n&&"function"==typeof(r=t.toString)&&!i(e=r.call(t)))return e;if("function"==typeof(r=t.valueOf)&&!i(e=r.call(t)))return e;if(!n&&"function"==typeof(r=t.toString)&&!i(e=r.call(t)))return e;throw TypeError("Can't convert object to primitive value")}},function(t,n,r){var d=r(6),y=r(19),g=r(93),b=r(13),x=r(9),m="prototype",S=function(t,n,r){var e,i,o,u=t&S.F,c=t&S.G,f=t&S.S,a=t&S.P,s=t&S.B,l=t&S.W,h=c?y:y[n]||(y[n]={}),v=h[m],p=c?d:f?d[n]:(d[n]||{})[m];for(e in c&&(r=n),r)(i=!u&&p&&void 0!==p[e])&&x(h,e)||(o=i?p[e]:r[e],h[e]=c&&"function"!=typeof p[e]?r[e]:s&&i?g(o,d):l&&p[e]==o?function(e){var t=function(t,n,r){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,n)}return new e(t,n,r)}return e.apply(this,arguments)};return t[m]=e[m],t}(o):a&&"function"==typeof o?g(Function.call,o):o,a&&((h.virtual||(h.virtual={}))[e]=o,t&S.R&&v&&!v[e]&&b(v,e,o)))};S.F=1,S.G=2,S.S=4,S.P=8,S.B=16,S.W=32,S.U=64,S.R=128,t.exports=S},function(t,n,r){var e=r(34);t.exports=function(t){return Object(e(t))}},function(t,n,r){var o=r(196),e=r(1),i=r(118)("metadata"),u=i.store||(i.store=new(r(200))),c=function(t,n,r){var e=u.get(t);if(!e){if(!r)return;u.set(t,e=new o)}var i=e.get(n);if(!i){if(!r)return;e.set(n,i=new o)}return i};t.exports={store:u,map:c,has:function(t,n,r){var e=c(n,r,!1);return void 0!==e&&e.has(t)},get:function(t,n,r){var e=c(n,r,!1);return void 0===e?void 0:e.get(t)},set:function(t,n,r,e){c(r,e,!0).set(t,n)},keys:function(t,n){var r=c(t,n,!1),e=[];return r&&r.forEach(function(t,n){e.push(n)}),e},key:function(t){return void 0===t||"symbol"==typeof t?t:String(t)},exp:function(t){e(e.S,"Reflect",t)}}},function(t,n,r){"use strict";if(r(10)){var g=r(68),b=r(3),x=r(4),m=r(1),S=r(132),e=r(159),h=r(47),w=r(70),i=r(75),_=r(26),o=r(76),u=r(49),O=r(8),E=r(194),c=r(78),f=r(53),a=r(30),M=r(81),P=r(5),v=r(17),p=r(145),j=r(72),F=r(32),A=r(73).f,d=r(161),s=r(79),l=r(7),y=r(50),I=r(120),L=r(119),N=r(162),T=r(82),k=r(125),R=r(77),C=r(137),D=r(166),G=r(11),W=r(31),U=G.f,V=W.f,B=b.RangeError,q=b.TypeError,z=b.Uint8Array,K="ArrayBuffer",H="Shared"+K,J="BYTES_PER_ELEMENT",$="prototype",Y=Array[$],X=e.ArrayBuffer,Q=e.DataView,Z=y(0),tt=y(2),nt=y(3),rt=y(4),et=y(5),it=y(6),ot=I(!0),ut=I(!1),ct=N.values,ft=N.keys,at=N.entries,st=Y.lastIndexOf,lt=Y.reduce,ht=Y.reduceRight,vt=Y.join,pt=Y.sort,dt=Y.slice,yt=Y.toString,gt=Y.toLocaleString,bt=l("iterator"),xt=l("toStringTag"),mt=s("typed_constructor"),St=s("def_constructor"),wt=S.CONSTR,_t=S.TYPED,Ot=S.VIEW,Et="Wrong length!",Mt=y(1,function(t,n){return It(L(t,t[St]),n)}),Pt=x(function(){return 1===new z(new Uint16Array([1]).buffer)[0]}),jt=!!z&&!!z[$].set&&x(function(){new z(1).set({})}),Ft=function(t,n){var r=u(t);if(r<0||r%n)throw B("Wrong offset!");return r},At=function(t){if(P(t)&&_t in t)return t;throw q(t+" is not a typed array!")},It=function(t,n){if(!(P(t)&&mt in t))throw q("It is not a typed array constructor!");return new t(n)},Lt=function(t,n){return Nt(L(t,t[St]),n)},Nt=function(t,n){for(var r=0,e=n.length,i=It(t,e);r<e;)i[r]=n[r++];return i},Tt=function(t,n,r){U(t,n,{get:function(){return this._d[r]}})},kt=function(t){var n,r,e,i,o,u,c=v(t),f=arguments.length,a=1<f?arguments[1]:void 0,s=void 0!==a,l=d(c);if(null!=l&&!p(l)){for(u=l.call(c),e=[],n=0;!(o=u.next()).done;n++)e.push(o.value);c=e}for(s&&2<f&&(a=h(a,arguments[2],2)),n=0,r=O(c.length),i=It(this,r);n<r;n++)i[n]=s?a(c[n],n):c[n];return i},Rt=function(){for(var t=0,n=arguments.length,r=It(this,n);t<n;)r[t]=arguments[t++];return r},Ct=!!z&&x(function(){gt.call(new z(1))}),Dt=function(){return gt.apply(Ct?dt.call(At(this)):At(this),arguments)},Gt={copyWithin:function(t,n){return D.call(At(this),t,n,2<arguments.length?arguments[2]:void 0)},every:function(t){return rt(At(this),t,1<arguments.length?arguments[1]:void 0)},fill:function(t){return C.apply(At(this),arguments)},filter:function(t){return Lt(this,tt(At(this),t,1<arguments.length?arguments[1]:void 0))},find:function(t){return et(At(this),t,1<arguments.length?arguments[1]:void 0)},findIndex:function(t){return it(At(this),t,1<arguments.length?arguments[1]:void 0)},forEach:function(t){Z(At(this),t,1<arguments.length?arguments[1]:void 0)},indexOf:function(t){return ut(At(this),t,1<arguments.length?arguments[1]:void 0)},includes:function(t){return ot(At(this),t,1<arguments.length?arguments[1]:void 0)},join:function(t){return vt.apply(At(this),arguments)},lastIndexOf:function(t){return st.apply(At(this),arguments)},map:function(t){return Mt(At(this),t,1<arguments.length?arguments[1]:void 0)},reduce:function(t){return lt.apply(At(this),arguments)},reduceRight:function(t){return ht.apply(At(this),arguments)},reverse:function(){for(var t,n=this,r=At(n).length,e=Math.floor(r/2),i=0;i<e;)t=n[i],n[i++]=n[--r],n[r]=t;return n},some:function(t){return nt(At(this),t,1<arguments.length?arguments[1]:void 0)},sort:function(t){return pt.call(At(this),t)},subarray:function(t,n){var r=At(this),e=r.length,i=c(t,e);return new(L(r,r[St]))(r.buffer,r.byteOffset+i*r.BYTES_PER_ELEMENT,O((void 0===n?e:c(n,e))-i))}},Wt=function(t,n){return Lt(this,dt.call(At(this),t,n))},Ut=function(t){At(this);var n=Ft(arguments[1],1),r=this.length,e=v(t),i=O(e.length),o=0;if(r<i+n)throw B(Et);for(;o<i;)this[n+o]=e[o++]},Vt={entries:function(){return at.call(At(this))},keys:function(){return ft.call(At(this))},values:function(){return ct.call(At(this))}},Bt=function(t,n){return P(t)&&t[_t]&&"symbol"!=typeof n&&n in t&&String(+n)==String(n)},qt=function(t,n){return Bt(t,n=f(n,!0))?i(2,t[n]):V(t,n)},zt=function(t,n,r){return!(Bt(t,n=f(n,!0))&&P(r)&&a(r,"value"))||a(r,"get")||a(r,"set")||r.configurable||a(r,"writable")&&!r.writable||a(r,"enumerable")&&!r.enumerable?U(t,n,r):(t[n]=r.value,t)};wt||(W.f=qt,G.f=zt),m(m.S+m.F*!wt,"Object",{getOwnPropertyDescriptor:qt,defineProperty:zt}),x(function(){yt.call({})})&&(yt=gt=function(){return vt.call(this)});var Kt=o({},Gt);o(Kt,Vt),_(Kt,bt,Vt.values),o(Kt,{slice:Wt,set:Ut,constructor:function(){},toString:yt,toLocaleString:Dt}),Tt(Kt,"buffer","b"),Tt(Kt,"byteOffset","o"),Tt(Kt,"byteLength","l"),Tt(Kt,"length","e"),U(Kt,xt,{get:function(){return this[_t]}}),t.exports=function(t,l,n,o){var h=t+((o=!!o)?"Clamped":"")+"Array",r="get"+t,u="set"+t,v=b[h],c=v||{},e=v&&F(v),i=!v||!S.ABV,f={},a=v&&v[$],p=function(t,i){U(t,i,{get:function(){return t=i,(n=this._d).v[r](t*l+n.o,Pt);var t,n},set:function(t){return n=i,r=t,e=this._d,o&&(r=(r=Math.round(r))<0?0:255<r?255:255&r),void e.v[u](n*l+e.o,r,Pt);var n,r,e},enumerable:!0})};i?(v=n(function(t,n,r,e){w(t,v,h,"_d");var i,o,u,c,f=0,a=0;if(P(n)){if(!(n instanceof X||(c=M(n))==K||c==H))return _t in n?Nt(v,n):kt.call(v,n);i=n,a=Ft(r,l);var s=n.byteLength;if(void 0===e){if(s%l)throw B(Et);if((o=s-a)<0)throw B(Et)}else if(s<(o=O(e)*l)+a)throw B(Et);u=o/l}else u=E(n),i=new X(o=u*l);for(_(t,"_d",{b:i,o:a,l:o,e:u,v:new Q(i)});f<u;)p(t,f++)}),a=v[$]=j(Kt),_(a,"constructor",v)):x(function(){v(1)})&&x(function(){new v(-1)})&&k(function(t){new v,new v(null),new v(1.5),new v(t)},!0)||(v=n(function(t,n,r,e){var i;return w(t,v,h),P(n)?n instanceof X||(i=M(n))==K||i==H?void 0!==e?new c(n,Ft(r,l),e):void 0!==r?new c(n,Ft(r,l)):new c(n):_t in n?Nt(v,n):kt.call(v,n):new c(E(n))}),Z(e!==Function.prototype?A(c).concat(A(e)):A(c),function(t){t in v||_(v,t,c[t])}),v[$]=a,g||(a.constructor=v));var s=a[bt],d=!!s&&("values"==s.name||null==s.name),y=Vt.values;_(v,mt,!0),_(a,_t,h),_(a,Ot,!0),_(a,St,v),(o?new v(1)[xt]==h:xt in a)||U(a,xt,{get:function(){return h}}),f[h]=v,m(m.G+m.W+m.F*(v!=c),f),m(m.S,h,{BYTES_PER_ELEMENT:l}),m(m.S+m.F*x(function(){c.of.call(v,1)}),h,{from:kt,of:Rt}),J in a||_(a,J,l),m(m.P,h,Gt),R(h),m(m.P+m.F*jt,h,{set:Ut}),m(m.P+m.F*!d,h,Vt),g||a.toString==yt||(a.toString=yt),m(m.P+m.F*x(function(){new v(1).slice()}),h,{slice:Wt}),m(m.P+m.F*(x(function(){return[1,2].toLocaleString()!=new v([1,2]).toLocaleString()})||!x(function(){a.toLocaleString.call([1,2])})),h,{toLocaleString:Dt}),T[h]=d?s:y,g||d||_(a,bt,y)}}else t.exports=function(){}},function(t,n){var r={}.toString;t.exports=function(t){return r.call(t).slice(8,-1)}},function(t,n,r){var e=r(18),i=r(6).document,o=e(i)&&e(i.createElement);t.exports=function(t){return o?i.createElement(t):{}}},function(t,n,r){t.exports=!r(12)&&!r(20)(function(){return 7!=Object.defineProperty(r(59)("div"),"a",{get:function(){return 7}}).a})},function(t,n,r){"use strict";var x=r(23),m=r(54),S=r(66),w=r(13),_=r(36),O=r(98),E=r(38),M=r(104),P=r(16)("iterator"),j=!([].keys&&"next"in[].keys()),F="values",A=function(){return this};t.exports=function(t,n,r,e,i,o,u){O(r,n,e);var c,f,a,s=function(t){if(!j&&t in p)return p[t];switch(t){case"keys":case F:return function(){return new r(this,t)}}return function(){return new r(this,t)}},l=n+" Iterator",h=i==F,v=!1,p=t.prototype,d=p[P]||p["@@iterator"]||i&&p[i],y=d||s(i),g=i?h?s("entries"):y:void 0,b="Array"==n&&p.entries||d;if(b&&((a=M(b.call(new t)))!==Object.prototype&&a.next&&(E(a,l,!0),x||"function"==typeof a[P]||w(a,P,A))),h&&d&&d.name!==F&&(v=!0,y=function(){return d.call(this)}),x&&!u||!j&&!v&&p[P]||w(p,P,y),_[n]=y,_[l]=A,i)if(c={values:h?y:s(F),keys:o?y:s("keys"),entries:g},u)for(f in c)f in p||S(p,f,c[f]);else m(m.P+m.F*(j||v),n,c);return c}},function(t,n,e){var i=e(22),o=e(101),u=e(35),c=e(39)("IE_PROTO"),f=function(){},a="prototype",s=function(){var t,n=e(59)("iframe"),r=u.length;for(n.style.display="none",e(95).appendChild(n),n.src="javascript:",(t=n.contentWindow.document).open(),t.write("<script>document.F=Object<\/script>"),t.close(),s=t.F;r--;)delete s[a][u[r]];return s()};t.exports=Object.create||function(t,n){var r;return null!==t?(f[a]=i(t),r=new f,f[a]=null,r[c]=t):r=s(),void 0===n?r:o(r,n)}},function(t,n,r){var e=r(65),i=r(35).concat("length","prototype");n.f=Object.getOwnPropertyNames||function(t){return e(t,i)}},function(t,n){n.f=Object.getOwnPropertySymbols},function(t,n,r){var u=r(9),c=r(15),f=r(92)(!1),a=r(39)("IE_PROTO");t.exports=function(t,n){var r,e=c(t),i=0,o=[];for(r in e)r!=a&&u(e,r)&&o.push(r);for(;n.length>i;)u(e,r=n[i++])&&(~f(o,r)||o.push(r));return o}},function(t,n,r){t.exports=r(13)},function(t,n,r){var e=r(7)("unscopables"),i=Array.prototype;null==i[e]&&r(26)(i,e,{}),t.exports=function(t){i[e][t]=!0}},function(t,n){t.exports=!1},function(t,n,r){var e=r(79)("meta"),i=r(5),o=r(30),u=r(11).f,c=0,f=Object.isExtensible||function(){return!0},a=!r(4)(function(){return f(Object.preventExtensions({}))}),s=function(t){u(t,e,{value:{i:"O"+ ++c,w:{}}})},l=t.exports={KEY:e,NEED:!1,fastKey:function(t,n){if(!i(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!o(t,e)){if(!f(t))return"F";if(!n)return"E";s(t)}return t[e].i},getWeak:function(t,n){if(!o(t,e)){if(!f(t))return!0;if(!n)return!1;s(t)}return t[e].w},onFreeze:function(t){return a&&l.NEED&&f(t)&&!o(t,e)&&s(t),t}}},function(t,n){t.exports=function(t,n,r,e){if(!(t instanceof n)||void 0!==e&&e in t)throw TypeError(r+": incorrect invocation!");return t}},function(t,n,r){var h=r(47),v=r(177),p=r(145),d=r(2),y=r(8),g=r(161),b={},x={};(n=t.exports=function(t,n,r,e,i){var o,u,c,f,a=i?function(){return t}:g(t),s=h(r,e,n?2:1),l=0;if("function"!=typeof a)throw TypeError(t+" is not iterable!");if(p(a)){for(o=y(t.length);l<o;l++)if((f=n?s(d(u=t[l])[0],u[1]):s(t[l]))===b||f===x)return f}else for(c=a.call(t);!(u=c.next()).done;)if((f=v(c,s,u.value,n))===b||f===x)return f}).BREAK=b,n.RETURN=x},function(t,n,e){var i=e(2),o=e(183),u=e(141),c=e(154)("IE_PROTO"),f=function(){},a="prototype",s=function(){var t,n=e(140)("iframe"),r=u.length;for(n.style.display="none",e(143).appendChild(n),n.src="javascript:",(t=n.contentWindow.document).open(),t.write("<script>document.F=Object<\/script>"),t.close(),s=t.F;r--;)delete s[a][u[r]];return s()};t.exports=Object.create||function(t,n){var r;return null!==t?(f[a]=i(t),r=new f,f[a]=null,r[c]=t):r=s(),void 0===n?r:o(r,n)}},function(t,n,r){var e=r(185),i=r(141).concat("length","prototype");n.f=Object.getOwnPropertyNames||function(t){return e(t,i)}},function(t,n,r){var e=r(185),i=r(141);t.exports=Object.keys||function(t){return e(t,i)}},function(t,n){t.exports=function(t,n){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:n}}},function(t,n,r){var i=r(27);t.exports=function(t,n,r){for(var e in n)i(t,e,n[e],r);return t}},function(t,n,r){"use strict";var e=r(3),i=r(11),o=r(10),u=r(7)("species");t.exports=function(t){var n=e[t];o&&n&&!n[u]&&i.f(n,u,{configurable:!0,get:function(){return this}})}},function(t,n,r){var e=r(49),i=Math.max,o=Math.min;t.exports=function(t,n){return(t=e(t))<0?i(t+n,0):o(t,n)}},function(t,n){var r=0,e=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++r+e).toString(36))}},function(t,n,r){var e=r(5);t.exports=function(t,n){if(!e(t)||t._t!==n)throw TypeError("Incompatible receiver, "+n+" required!");return t}},function(t,n,r){var i=r(45),o=r(7)("toStringTag"),u="Arguments"==i(function(){return arguments}());t.exports=function(t){var n,r,e;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(r=function(t,n){try{return t[n]}catch(t){}}(n=Object(t),o))?r:u?i(n):"Object"==(e=i(n))&&"function"==typeof n.callee?"Arguments":e}},function(t,n){t.exports={}},function(t,n,r){var e=r(11).f,i=r(30),o=r(7)("toStringTag");t.exports=function(t,n,r){t&&!i(t=r?t:t.prototype,o)&&e(t,o,{configurable:!0,value:n})}},function(t,n,r){var u=r(1),e=r(51),c=r(4),f=r(157),i="["+f+"]",o=RegExp("^"+i+i+"*"),a=RegExp(i+i+"*$"),s=function(t,n,r){var e={},i=c(function(){return!!f[t]()||"​"!="​"[t]()}),o=e[t]=i?n(l):f[t];r&&(e[r]=o),u(u.P+u.F*i,"String",e)},l=s.trim=function(t,n){return t=String(e(t)),1&n&&(t=t.replace(o,"")),2&n&&(t=t.replace(a,"")),t};t.exports=s},function(t,n,r){t.exports={default:r(88),__esModule:!0}},function(t,n,r){t.exports={default:r(89),__esModule:!0}},function(t,n,r){"use strict";function e(t){return t&&t.__esModule?t:{default:t}}n.__esModule=!0;var i=e(r(86)),o=e(r(85)),u="function"==typeof o.default&&"symbol"==typeof i.default?function(t){return typeof t}:function(t){return t&&"function"==typeof o.default&&t.constructor===o.default&&t!==o.default.prototype?"symbol":typeof t};n.default="function"==typeof o.default&&"symbol"===u(i.default)?function(t){return void 0===t?"undefined":u(t)}:function(t){return t&&"function"==typeof o.default&&t.constructor===o.default&&t!==o.default.prototype?"symbol":void 0===t?"undefined":u(t)}},function(t,n,r){r(111),r(109),r(112),r(113),t.exports=r(19).Symbol},function(t,n,r){r(110),r(114),t.exports=r(44).f("iterator")},function(t,n){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,n){t.exports=function(){}},function(t,n,r){var f=r(15),a=r(107),s=r(106);t.exports=function(c){return function(t,n,r){var e,i=f(t),o=a(i.length),u=s(r,o);if(c&&n!=n){for(;u<o;)if((e=i[u++])!=e)return!0}else for(;u<o;u++)if((c||u in i)&&i[u]===n)return c||u||0;return!c&&-1}}},function(t,n,r){var o=r(90);t.exports=function(e,i,t){if(o(e),void 0===i)return e;switch(t){case 1:return function(t){return e.call(i,t)};case 2:return function(t,n){return e.call(i,t,n)};case 3:return function(t,n,r){return e.call(i,t,n,r)}}return function(){return e.apply(i,arguments)}}},function(t,n,r){var c=r(29),f=r(64),a=r(37);t.exports=function(t){var n=c(t),r=f.f;if(r)for(var e,i=r(t),o=a.f,u=0;i.length>u;)o.call(t,e=i[u++])&&n.push(e);return n}},function(t,n,r){var e=r(6).document;t.exports=e&&e.documentElement},function(t,n,r){var e=r(58);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==e(t)?t.split(""):Object(t)}},function(t,n,r){var e=r(58);t.exports=Array.isArray||function(t){return"Array"==e(t)}},function(t,n,r){"use strict";var e=r(62),i=r(24),o=r(38),u={};r(13)(u,r(16)("iterator"),function(){return this}),t.exports=function(t,n,r){t.prototype=e(u,{next:i(1,r)}),o(t,n+" Iterator")}},function(t,n){t.exports=function(t,n){return{value:n,done:!!t}}},function(t,n,r){var e=r(25)("meta"),i=r(18),o=r(9),u=r(14).f,c=0,f=Object.isExtensible||function(){return!0},a=!r(20)(function(){return f(Object.preventExtensions({}))}),s=function(t){u(t,e,{value:{i:"O"+ ++c,w:{}}})},l=t.exports={KEY:e,NEED:!1,fastKey:function(t,n){if(!i(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!o(t,e)){if(!f(t))return"F";if(!n)return"E";s(t)}return t[e].i},getWeak:function(t,n){if(!o(t,e)){if(!f(t))return!0;if(!n)return!1;s(t)}return t[e].w},onFreeze:function(t){return a&&l.NEED&&f(t)&&!o(t,e)&&s(t),t}}},function(t,n,r){var u=r(14),c=r(22),f=r(29);t.exports=r(12)?Object.defineProperties:function(t,n){c(t);for(var r,e=f(n),i=e.length,o=0;o<i;)u.f(t,r=e[o++],n[r]);return t}},function(t,n,r){var e=r(37),i=r(24),o=r(15),u=r(42),c=r(9),f=r(60),a=Object.getOwnPropertyDescriptor;n.f=r(12)?a:function(t,n){if(t=o(t),n=u(n,!0),f)try{return a(t,n)}catch(t){}if(c(t,n))return i(!e.f.call(t,n),t[n])}},function(t,n,r){var e=r(15),i=r(63).f,o={}.toString,u="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];t.exports.f=function(t){return u&&"[object Window]"==o.call(t)?function(t){try{return i(t)}catch(t){return u.slice()}}(t):i(e(t))}},function(t,n,r){var e=r(9),i=r(55),o=r(39)("IE_PROTO"),u=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=i(t),e(t,o)?t[o]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?u:null}},function(t,n,r){var f=r(41),a=r(34);t.exports=function(c){return function(t,n){var r,e,i=String(a(t)),o=f(n),u=i.length;return o<0||u<=o?c?"":void 0:(r=i.charCodeAt(o))<55296||56319<r||o+1===u||(e=i.charCodeAt(o+1))<56320||57343<e?c?i.charAt(o):r:c?i.slice(o,o+2):e-56320+(r-55296<<10)+65536}}},function(t,n,r){var e=r(41),i=Math.max,o=Math.min;t.exports=function(t,n){return(t=e(t))<0?i(t+n,0):o(t,n)}},function(t,n,r){var e=r(41),i=Math.min;t.exports=function(t){return 0<t?i(e(t),9007199254740991):0}},function(t,n,r){"use strict";var e=r(91),i=r(99),o=r(36),u=r(15);t.exports=r(61)(Array,"Array",function(t,n){this._t=u(t),this._i=0,this._k=n},function(){var t=this._t,n=this._k,r=this._i++;return!t||r>=t.length?(this._t=void 0,i(1)):i(0,"keys"==n?r:"values"==n?t[r]:[r,t[r]])},"values"),o.Arguments=o.Array,e("keys"),e("values"),e("entries")},function(t,n){},function(t,n,r){"use strict";var e=r(105)(!0);r(61)(String,"String",function(t){this._t=String(t),this._i=0},function(){var t,n=this._t,r=this._i;return r>=n.length?{value:void 0,done:!0}:(t=e(n,r),this._i+=t.length,{value:t,done:!1})})},function(t,n,r){"use strict";var e=r(6),u=r(9),i=r(12),o=r(54),c=r(66),f=r(100).KEY,a=r(20),s=r(40),l=r(38),h=r(25),v=r(16),p=r(44),d=r(43),y=r(94),g=r(97),b=r(22),x=r(18),m=r(55),S=r(15),w=r(42),_=r(24),O=r(62),E=r(103),M=r(102),P=r(64),j=r(14),F=r(29),A=M.f,I=j.f,L=E.f,N=e.Symbol,T=e.JSON,k=T&&T.stringify,R="prototype",C=v("_hidden"),D=v("toPrimitive"),G={}.propertyIsEnumerable,W=s("symbol-registry"),U=s("symbols"),V=s("op-symbols"),B=Object[R],q="function"==typeof N&&!!P.f,z=e.QObject,K=!z||!z[R]||!z[R].findChild,H=i&&a(function(){return 7!=O(I({},"a",{get:function(){return I(this,"a",{value:7}).a}})).a})?function(t,n,r){var e=A(B,n);e&&delete B[n],I(t,n,r),e&&t!==B&&I(B,n,e)}:I,J=function(t){var n=U[t]=O(N[R]);return n._k=t,n},$=q&&"symbol"==typeof N.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof N},Y=function(t,n,r){return t===B&&Y(V,n,r),b(t),n=w(n,!0),b(r),u(U,n)?(r.enumerable?(u(t,C)&&t[C][n]&&(t[C][n]=!1),r=O(r,{enumerable:_(0,!1)})):(u(t,C)||I(t,C,_(1,{})),t[C][n]=!0),H(t,n,r)):I(t,n,r)},X=function(t,n){b(t);for(var r,e=y(n=S(n)),i=0,o=e.length;i<o;)Y(t,r=e[i++],n[r]);return t},Q=function(t){var n=G.call(this,t=w(t,!0));return!(this===B&&u(U,t)&&!u(V,t))&&(!(n||!u(this,t)||!u(U,t)||u(this,C)&&this[C][t])||n)},Z=function(t,n){if(t=S(t),n=w(n,!0),t!==B||!u(U,n)||u(V,n)){var r=A(t,n);return!r||!u(U,n)||u(t,C)&&t[C][n]||(r.enumerable=!0),r}},tt=function(t){for(var n,r=L(S(t)),e=[],i=0;r.length>i;)u(U,n=r[i++])||n==C||n==f||e.push(n);return e},nt=function(t){for(var n,r=t===B,e=L(r?V:S(t)),i=[],o=0;e.length>o;)!u(U,n=e[o++])||r&&!u(B,n)||i.push(U[n]);return i};q||(c((N=function(){if(this instanceof N)throw TypeError("Symbol is not a constructor!");var n=h(0<arguments.length?arguments[0]:void 0),r=function(t){this===B&&r.call(V,t),u(this,C)&&u(this[C],n)&&(this[C][n]=!1),H(this,n,_(1,t))};return i&&K&&H(B,n,{configurable:!0,set:r}),J(n)})[R],"toString",function(){return this._k}),M.f=Z,j.f=Y,r(63).f=E.f=tt,r(37).f=Q,P.f=nt,i&&!r(23)&&c(B,"propertyIsEnumerable",Q,!0),p.f=function(t){return J(v(t))}),o(o.G+o.W+o.F*!q,{Symbol:N});for(var rt="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),et=0;rt.length>et;)v(rt[et++]);for(var it=F(v.store),ot=0;it.length>ot;)d(it[ot++]);o(o.S+o.F*!q,"Symbol",{for:function(t){return u(W,t+="")?W[t]:W[t]=N(t)},keyFor:function(t){if(!$(t))throw TypeError(t+" is not a symbol!");for(var n in W)if(W[n]===t)return n},useSetter:function(){K=!0},useSimple:function(){K=!1}}),o(o.S+o.F*!q,"Object",{create:function(t,n){return void 0===n?O(t):X(O(t),n)},defineProperty:Y,defineProperties:X,getOwnPropertyDescriptor:Z,getOwnPropertyNames:tt,getOwnPropertySymbols:nt});var ut=a(function(){P.f(1)});o(o.S+o.F*ut,"Object",{getOwnPropertySymbols:function(t){return P.f(m(t))}}),T&&o(o.S+o.F*(!q||a(function(){var t=N();return"[null]"!=k([t])||"{}"!=k({a:t})||"{}"!=k(Object(t))})),"JSON",{stringify:function(t){for(var n,r,e=[t],i=1;arguments.length>i;)e.push(arguments[i++]);if(r=n=e[1],(x(n)||void 0!==t)&&!$(t))return g(n)||(n=function(t,n){if("function"==typeof r&&(n=r.call(this,t,n)),!$(n))return n}),e[1]=n,k.apply(T,e)}}),N[R][D]||r(13)(N[R],D,N[R].valueOf),l(N,"Symbol"),l(Math,"Math",!0),l(e.JSON,"JSON",!0)},function(t,n,r){r(43)("asyncIterator")},function(t,n,r){r(43)("observable")},function(t,n,r){r(108);for(var e=r(6),i=r(13),o=r(36),u=r(16)("toStringTag"),c="CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,TextTrackList,TouchList".split(","),f=0;f<c.length;f++){var a=c[f],s=e[a],l=s&&s.prototype;l&&!l[u]&&i(l,u,a),o[a]=o.Array}},function(t,n,r){"use strict";var e=r(2);t.exports=function(){var t=e(this),n="";return t.global&&(n+="g"),t.ignoreCase&&(n+="i"),t.multiline&&(n+="m"),t.unicode&&(n+="u"),t.sticky&&(n+="y"),n}},function(t,n,r){var e=r(45);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==e(t)?t.split(""):Object(t)}},function(t,n){n.f={}.propertyIsEnumerable},function(t,n,r){var e=r(46),i=r(3),o="__core-js_shared__",u=i[o]||(i[o]={});(t.exports=function(t,n){return u[t]||(u[t]=void 0!==n?n:{})})("versions",[]).push({version:e.version,mode:r(68)?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},function(t,n,r){var i=r(2),o=r(21),u=r(7)("species");t.exports=function(t,n){var r,e=i(t).constructor;return void 0===e||null==(r=i(e)[u])?n:o(r)}},function(t,n,r){var f=r(33),a=r(8),s=r(78);t.exports=function(c){return function(t,n,r){var e,i=f(t),o=a(i.length),u=s(r,o);if(c&&n!=n){for(;u<o;)if((e=i[u++])!=e)return!0}else for(;u<o;u++)if((c||u in i)&&i[u]===n)return c||u||0;return!c&&-1}}},function(t,n,r){"use strict";var g=r(3),b=r(1),x=r(27),m=r(76),S=r(69),w=r(71),_=r(70),O=r(5),E=r(4),M=r(125),P=r(83),j=r(144);t.exports=function(e,t,n,r,i,o){var u=g[e],c=u,f=i?"set":"add",a=c&&c.prototype,s={},l=function(t){var r=a[t];x(a,t,"delete"==t?function(t){return!(o&&!O(t))&&r.call(this,0===t?0:t)}:"has"==t?function(t){return!(o&&!O(t))&&r.call(this,0===t?0:t)}:"get"==t?function(t){return o&&!O(t)?void 0:r.call(this,0===t?0:t)}:"add"==t?function(t){return r.call(this,0===t?0:t),this}:function(t,n){return r.call(this,0===t?0:t,n),this})};if("function"==typeof c&&(o||a.forEach&&!E(function(){(new c).entries().next()}))){var h=new c,v=h[f](o?{}:-0,1)!=h,p=E(function(){h.has(1)}),d=M(function(t){new c(t)}),y=!o&&E(function(){for(var t=new c,n=5;n--;)t[f](n,n);return!t.has(-0)});d||(((c=t(function(t,n){_(t,c,e);var r=j(new u,t,c);return null!=n&&w(n,i,r[f],r),r})).prototype=a).constructor=c),(p||y)&&(l("delete"),l("has"),i&&l("get")),(y||v)&&l(f),o&&a.clear&&delete a.clear}else c=r.getConstructor(t,e,i,f),m(c.prototype,n),S.NEED=!0;return P(c,e),s[e]=c,b(b.G+b.W+b.F*(c!=u),s),o||r.setStrong(c,e,i),c}},function(t,n,r){"use strict";r(197);var s=r(27),l=r(26),h=r(4),v=r(51),p=r(7),d=r(152),y=p("species"),g=!h(function(){var t=/./;return t.exec=function(){var t=[];return t.groups={a:"7"},t},"7"!=="".replace(t,"$<a>")}),b=function(){var t=/(?:)/,n=t.exec;t.exec=function(){return n.apply(this,arguments)};var r="ab".split(t);return 2===r.length&&"a"===r[0]&&"b"===r[1]}();t.exports=function(r,t,n){var e=p(r),o=!h(function(){var t={};return t[e]=function(){return 7},7!=""[r](t)}),i=o?!h(function(){var t=!1,n=/a/;return n.exec=function(){return t=!0,null},"split"===r&&(n.constructor={},n.constructor[y]=function(){return n}),n[e](""),!t}):void 0;if(!o||!i||"replace"===r&&!g||"split"===r&&!b){var u=/./[e],c=n(v,e,""[r],function(t,n,r,e,i){return n.exec===d?o&&!i?{done:!0,value:u.call(n,r,e)}:{done:!0,value:t.call(r,n,e)}:{done:!1}}),f=c[0],a=c[1];s(String.prototype,r,f),l(RegExp.prototype,e,2==t?function(t,n){return a.call(t,this,n)}:function(t){return a.call(t,this)})}}},function(t,n,r){var e=r(45);t.exports=Array.isArray||function(t){return"Array"==e(t)}},function(t,n,r){var e=r(5),i=r(45),o=r(7)("match");t.exports=function(t){var n;return e(t)&&(void 0!==(n=t[o])?!!n:"RegExp"==i(t))}},function(t,n,r){var o=r(7)("iterator"),u=!1;try{var e=[7][o]();e.return=function(){u=!0},Array.from(e,function(){throw 2})}catch(t){}t.exports=function(t,n){if(!n&&!u)return!1;var r=!1;try{var e=[7],i=e[o]();i.next=function(){return{done:r=!0}},e[o]=function(){return i},t(e)}catch(t){}return r}},function(t,n,r){"use strict";t.exports=r(68)||!r(4)(function(){var t=Math.random();__defineSetter__.call(null,t,function(){}),delete r(3)[t]})},function(t,n){n.f=Object.getOwnPropertySymbols},function(t,n,r){"use strict";var i=r(81),o=RegExp.prototype.exec;t.exports=function(t,n){var r=t.exec;if("function"==typeof r){var e=r.call(t,n);if("object"!=typeof e)throw new TypeError("RegExp exec method returned something other than an Object or null");return e}if("RegExp"!==i(t))throw new TypeError("RegExp#exec called on incompatible receiver");return o.call(t,n)}},function(t,n,r){"use strict";var e=r(1),u=r(21),c=r(47),f=r(71);t.exports=function(t){e(e.S,t,{from:function(t){var n,r,e,i,o=arguments[1];return u(this),(n=void 0!==o)&&u(o),null==t?new this:(r=[],n?(e=0,i=c(o,arguments[2],2),f(t,!1,function(t){r.push(i(t,e++))})):f(t,!1,r.push,r),new this(r))}})}},function(t,n,r){"use strict";var e=r(1);t.exports=function(t){e(e.S,t,{of:function(){for(var t=arguments.length,n=new Array(t);t--;)n[t]=arguments[t];return new this(n)}})}},function(t,n,r){var f=r(49),a=r(51);t.exports=function(c){return function(t,n){var r,e,i=String(a(t)),o=f(n),u=i.length;return o<0||u<=o?c?"":void 0:(r=i.charCodeAt(o))<55296||56319<r||o+1===u||(e=i.charCodeAt(o+1))<56320||57343<e?c?i.charAt(o):r:c?i.slice(o,o+2):e-56320+(r-55296<<10)+65536}}},function(t,n,r){for(var e,i=r(3),o=r(26),u=r(79),c=u("typed_array"),f=u("view"),a=!(!i.ArrayBuffer||!i.DataView),s=a,l=0,h="Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array".split(",");l<9;)(e=i[h[l++]])?(o(e.prototype,c,!0),o(e.prototype,f,!0)):s=!1;t.exports={ABV:a,CONSTR:s,TYPED:c,VIEW:f}},function(t,n,r){var e=r(3).navigator;t.exports=e&&e.userAgent||""},function(t,n){"use strict";var r,e={versions:(r=window.navigator.userAgent,{trident:-1<r.indexOf("Trident"),presto:-1<r.indexOf("Presto"),webKit:-1<r.indexOf("AppleWebKit"),gecko:-1<r.indexOf("Gecko")&&-1==r.indexOf("KHTML"),mobile:!!r.match(/AppleWebKit.*Mobile.*/),ios:!!r.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),android:-1<r.indexOf("Android")||-1<r.indexOf("Linux"),iPhone:-1<r.indexOf("iPhone")||-1<r.indexOf("Mac"),iPad:-1<r.indexOf("iPad"),webApp:-1==r.indexOf("Safari"),weixin:-1==r.indexOf("MicroMessenger")})};t.exports=e},function(t,n,r){"use strict";var e,i=r(87),l=(e=i)&&e.__esModule?e:{default:e},h=function(){function n(t,n,r){return n||r?String.fromCharCode(n||r):o[t]||t}function r(t){return s[t]}var e=/&quot;|&lt;|&gt;|&amp;|&nbsp;|&apos;|&#(\d+);|&#(\d+)/g,i=/['<> "&]/g,o={"&quot;":'"',"&lt;":"<","&gt;":">","&amp;":"&","&nbsp;":" "},u=/\u00a0/g,c=/<br\s*\/?>/gi,f=/\r?\n/g,a=/\s/g,s={};for(var t in o)s[o[t]]=t;return o["&apos;"]="'",s["'"]="&#39;",{encode:function(t){return t?(""+t).replace(i,r).replace(f,"<br/>").replace(a,"&nbsp;"):""},decode:function(t){return t?(""+t).replace(c,"\n").replace(e,n).replace(u," "):""},encodeBase16:function(t){if(!t)return t;for(var n=[],r=0,e=(t+="").length;r<e;r++)n.push(t.charCodeAt(r).toString(16).toUpperCase());return n.join("")},encodeBase16forJSON:function(t){if(!t)return t;for(var n=[],r=0,e=(t=t.replace(/[\u4E00-\u9FBF]/gi,function(t){return escape(t).replace("%u","\\u")})).length;r<e;r++)n.push(t.charCodeAt(r).toString(16).toUpperCase());return n.join("")},decodeBase16:function(t){if(!t)return t;for(var n=[],r=0,e=(t+="").length;r<e;r+=2)n.push(String.fromCharCode("0x"+t.slice(r,r+2)));return n.join("")},encodeObject:function(t){if(t instanceof Array)for(var n=0,r=t.length;n<r;n++)t[n]=h.encodeObject(t[n]);else if("object"==(void 0===t?"undefined":(0,l.default)(t)))for(var e in t)t[e]=h.encodeObject(t[e]);else if("string"==typeof t)return h.encode(t);return t},loadScript:function(t){var n=document.createElement("script");document.getElementsByTagName("body")[0].appendChild(n),n.setAttribute("src",t)},addLoadEvent:function(t){var n=window.onload;"function"!=typeof window.onload?window.onload=t:window.onload=function(){n(),t()}}}}();t.exports=h},function(t,n,r){"use strict";var e=r(131)(!0);t.exports=function(t,n,r){return n+(r?e(t,n).length:1)}},function(t,n,r){"use strict";var c=r(17),f=r(78),a=r(8);t.exports=function(t){for(var n=c(this),r=a(n.length),e=arguments.length,i=f(1<e?arguments[1]:void 0,r),o=2<e?arguments[2]:void 0,u=void 0===o?r:f(o,r);i<u;)n[i++]=t;return n}},function(t,n,r){var e=r(215);t.exports=function(t,n){return new(e(t))(n)}},function(t,n,r){"use strict";var e=r(11),i=r(75);t.exports=function(t,n,r){n in t?e.f(t,n,i(0,r)):t[n]=r}},function(t,n,r){var e=r(5),i=r(3).document,o=e(i)&&e(i.createElement);t.exports=function(t){return o?i.createElement(t):{}}},function(t,n){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,n,r){var e=r(7)("match");t.exports=function(n){var r=/./;try{"/./"[n](r)}catch(t){try{return r[e]=!1,!"/./"[n](r)}catch(n){}}return!0}},function(t,n,r){var e=r(3).document;t.exports=e&&e.documentElement},function(t,n,r){var o=r(5),u=r(153).set;t.exports=function(t,n,r){var e,i=n.constructor;return i!==r&&"function"==typeof i&&(e=i.prototype)!==r.prototype&&o(e)&&u&&u(t,e),t}},function(t,n,r){var e=r(82),i=r(7)("iterator"),o=Array.prototype;t.exports=function(t){return void 0!==t&&(e.Array===t||o[i]===t)}},function(t,n,r){"use strict";var e=r(72),i=r(75),o=r(83),u={};r(26)(u,r(7)("iterator"),function(){return this}),t.exports=function(t,n,r){t.prototype=e(u,{next:i(1,r)}),o(t,n+" Iterator")}},function(t,n,r){"use strict";var x=r(68),m=r(1),S=r(27),w=r(26),_=r(82),O=r(146),E=r(83),M=r(32),P=r(7)("iterator"),j=!([].keys&&"next"in[].keys()),F="values",A=function(){return this};t.exports=function(t,n,r,e,i,o,u){O(r,n,e);var c,f,a,s=function(t){if(!j&&t in p)return p[t];switch(t){case"keys":case F:return function(){return new r(this,t)}}return function(){return new r(this,t)}},l=n+" Iterator",h=i==F,v=!1,p=t.prototype,d=p[P]||p["@@iterator"]||i&&p[i],y=d||s(i),g=i?h?s("entries"):y:void 0,b="Array"==n&&p.entries||d;if(b&&((a=M(b.call(new t)))!==Object.prototype&&a.next&&(E(a,l,!0),x||"function"==typeof a[P]||w(a,P,A))),h&&d&&d.name!==F&&(v=!0,y=function(){return d.call(this)}),x&&!u||!j&&!v&&p[P]||w(p,P,y),_[n]=y,_[l]=A,i)if(c={values:h?y:s(F),keys:o?y:s("keys"),entries:g},u)for(f in c)f in p||S(p,f,c[f]);else m(m.P+m.F*(j||v),n,c);return c}},function(t,n){var r=Math.expm1;t.exports=!r||22025.465794806718<r(10)||r(10)<22025.465794806718||-2e-17!=r(-2e-17)?function(t){return 0==(t=+t)?t:-1e-6<t&&t<1e-6?t+t*t/2:Math.exp(t)-1}:r},function(t,n){t.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:t<0?-1:1}},function(t,n,r){var c=r(3),f=r(158).set,a=c.MutationObserver||c.WebKitMutationObserver,s=c.process,l=c.Promise,h="process"==r(45)(s);t.exports=function(){var r,e,i,t=function(){var t,n;for(h&&(t=s.domain)&&t.exit();r;){n=r.fn,r=r.next;try{n()}catch(t){throw r?i():e=void 0,t}}e=void 0,t&&t.enter()};if(h)i=function(){s.nextTick(t)};else if(!a||c.navigator&&c.navigator.standalone)if(l&&l.resolve){var n=l.resolve(void 0);i=function(){n.then(t)}}else i=function(){f.call(c,t)};else{var o=!0,u=document.createTextNode("");new a(t).observe(u,{characterData:!0}),i=function(){u.data=o=!o}}return function(t){var n={fn:t,next:void 0};e&&(e.next=n),r||(r=n,i()),e=n}}},function(t,n,r){"use strict";function e(t){var r,e;this.promise=new t(function(t,n){if(void 0!==r||void 0!==e)throw TypeError("Bad Promise constructor");r=t,e=n}),this.resolve=i(r),this.reject=i(e)}var i=r(21);t.exports.f=function(t){return new e(t)}},function(t,n,r){"use strict";var e,i,u=r(115),c=RegExp.prototype.exec,f=String.prototype.replace,o=c,a="lastIndex",s=(e=/a/,i=/b*/g,c.call(e,"a"),c.call(i,"a"),0!==e[a]||0!==i[a]),l=void 0!==/()??/.exec("")[1];(s||l)&&(o=function(t){var n,r,e,i,o=this;return l&&(r=new RegExp("^"+o.source+"$(?!\\s)",u.call(o))),s&&(n=o[a]),e=c.call(o,t),s&&e&&(o[a]=o.global?e.index+e[0].length:n),l&&e&&1<e.length&&f.call(e[0],r,function(){for(i=1;i<arguments.length-2;i++)void 0===arguments[i]&&(e[i]=void 0)}),e}),t.exports=o},function(t,n,i){var r=i(5),e=i(2),o=function(t,n){if(e(t),!r(n)&&null!==n)throw TypeError(n+": can't set as prototype!")};t.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(t,r,e){try{(e=i(47)(Function.call,i(31).f(Object.prototype,"__proto__").set,2))(t,[]),r=!(t instanceof Array)}catch(t){r=!0}return function(t,n){return o(t,n),r?t.__proto__=n:e(t,n),t}}({},!1):void 0),check:o}},function(t,n,r){var e=r(118)("keys"),i=r(79);t.exports=function(t){return e[t]||(e[t]=i(t))}},function(t,n,r){var e=r(124),i=r(51);t.exports=function(t,n,r){if(e(n))throw TypeError("String#"+r+" doesn't accept regex!");return String(i(t))}},function(t,n,r){"use strict";var i=r(49),o=r(51);t.exports=function(t){var n=String(o(this)),r="",e=i(t);if(e<0||e==1/0)throw RangeError("Count can't be negative");for(;0<e;(e>>>=1)&&(n+=n))1&e&&(r+=n);return r}},function(t,n){t.exports="\t\n\v\f\r   ᠎             　\u2028\u2029\ufeff"},function(t,n,r){var e,i,o,u=r(47),c=r(175),f=r(143),a=r(140),s=r(3),l=s.process,h=s.setImmediate,v=s.clearImmediate,p=s.MessageChannel,d=s.Dispatch,y=0,g={},b="onreadystatechange",x=function(){var t=+this;if(g.hasOwnProperty(t)){var n=g[t];delete g[t],n()}},m=function(t){x.call(t.data)};h&&v||(h=function(t){for(var n=[],r=1;arguments.length>r;)n.push(arguments[r++]);return g[++y]=function(){c("function"==typeof t?t:Function(t),n)},e(y),y},v=function(t){delete g[t]},"process"==r(45)(l)?e=function(t){l.nextTick(u(x,t,1))}:d&&d.now?e=function(t){d.now(u(x,t,1))}:p?(o=(i=new p).port2,i.port1.onmessage=m,e=u(o.postMessage,o,1)):s.addEventListener&&"function"==typeof postMessage&&!s.importScripts?(e=function(t){s.postMessage(t+"","*")},s.addEventListener("message",m,!1)):e=b in a("script")?function(t){f.appendChild(a("script"))[b]=function(){f.removeChild(this),x.call(t)}}:function(t){setTimeout(u(x,t,1),0)}),t.exports={set:h,clear:v}},function(t,n,r){"use strict";function e(t,n,r){var e,i,o,u=new Array(r),c=8*r-n-1,f=(1<<c)-1,a=f>>1,s=23===n?W(2,-24)-W(2,-77):0,l=0,h=t<0||0===t&&1/t<0?1:0;for((t=G(t))!=t||t===C?(i=t!=t?1:0,e=f):(e=U(V(t)/B),t*(o=W(2,-e))<1&&(e--,o*=2),2<=(t+=1<=e+a?s/o:s*W(2,1-a))*o&&(e++,o/=2),f<=e+a?(i=0,e=f):1<=e+a?(i=(t*o-1)*W(2,n),e+=a):(i=t*W(2,a-1)*W(2,n),e=0));8<=n;u[l++]=255&i,i/=256,n-=8);for(e=e<<n|i,c+=n;0<c;u[l++]=255&e,e/=256,c-=8);return u[--l]|=128*h,u}function i(t,n,r){var e,i=8*r-n-1,o=(1<<i)-1,u=o>>1,c=i-7,f=r-1,a=t[f--],s=127&a;for(a>>=7;0<c;s=256*s+t[f],f--,c-=8);for(e=s&(1<<-c)-1,s>>=-c,c+=n;0<c;e=256*e+t[f],f--,c-=8);if(0===s)s=1-u;else{if(s===o)return e?NaN:a?-C:C;e+=W(2,n),s-=u}return(a?-1:1)*e*W(2,s-n)}function o(t){return t[3]<<24|t[2]<<16|t[1]<<8|t[0]}function u(t){return[255&t]}function c(t){return[255&t,t>>8&255]}function f(t){return[255&t,t>>8&255,t>>16&255,t>>24&255]}function a(t){return e(t,52,8)}function s(t){return e(t,23,4)}function l(t,n,r){M(t[I],n,{get:function(){return this[r]}})}function h(t,n,r,e){var i=O(+r);if(i+n>t[H])throw R(L);var o=t[K]._b,u=i+t[J],c=o.slice(u,u+n);return e?c:c.reverse()}function v(t,n,r,e,i,o){var u=O(+r);if(u+n>t[H])throw R(L);for(var c=t[K]._b,f=u+t[J],a=e(+i),s=0;s<n;s++)c[f+s]=a[o?s:n-s-1]}var p=r(3),d=r(10),y=r(68),g=r(132),b=r(26),x=r(76),m=r(4),S=r(70),w=r(49),_=r(8),O=r(194),E=r(73).f,M=r(11).f,P=r(137),j=r(83),F="ArrayBuffer",A="DataView",I="prototype",L="Wrong index!",N=p[F],T=p[A],k=p.Math,R=p.RangeError,C=p.Infinity,D=N,G=k.abs,W=k.pow,U=k.floor,V=k.log,B=k.LN2,q="byteLength",z="byteOffset",K=d?"_b":"buffer",H=d?"_l":q,J=d?"_o":z;if(g.ABV){if(!m(function(){N(1)})||!m(function(){new N(-1)})||m(function(){return new N,new N(1.5),new N(NaN),N.name!=F})){for(var $,Y=(N=function(t){return S(this,N),new D(O(t))})[I]=D[I],X=E(D),Q=0;X.length>Q;)($=X[Q++])in N||b(N,$,D[$]);y||(Y.constructor=N)}var Z=new T(new N(2)),tt=T[I].setInt8;Z.setInt8(0,2147483648),Z.setInt8(1,2147483649),!Z.getInt8(0)&&Z.getInt8(1)||x(T[I],{setInt8:function(t,n){tt.call(this,t,n<<24>>24)},setUint8:function(t,n){tt.call(this,t,n<<24>>24)}},!0)}else N=function(t){S(this,N,F);var n=O(t);this._b=P.call(new Array(n),0),this[H]=n},T=function(t,n,r){S(this,T,A),S(t,N,A);var e=t[H],i=w(n);if(i<0||e<i)throw R("Wrong offset!");if(e<i+(r=void 0===r?e-i:_(r)))throw R("Wrong length!");this[K]=t,this[J]=i,this[H]=r},d&&(l(N,q,"_l"),l(T,"buffer","_b"),l(T,q,"_l"),l(T,z,"_o")),x(T[I],{getInt8:function(t){return h(this,1,t)[0]<<24>>24},getUint8:function(t){return h(this,1,t)[0]},getInt16:function(t){var n=h(this,2,t,arguments[1]);return(n[1]<<8|n[0])<<16>>16},getUint16:function(t){var n=h(this,2,t,arguments[1]);return n[1]<<8|n[0]},getInt32:function(t){return o(h(this,4,t,arguments[1]))},getUint32:function(t){return o(h(this,4,t,arguments[1]))>>>0},getFloat32:function(t){return i(h(this,4,t,arguments[1]),23,4)},getFloat64:function(t){return i(h(this,8,t,arguments[1]),52,8)},setInt8:function(t,n){v(this,1,t,u,n)},setUint8:function(t,n){v(this,1,t,u,n)},setInt16:function(t,n){v(this,2,t,c,n,arguments[2])},setUint16:function(t,n){v(this,2,t,c,n,arguments[2])},setInt32:function(t,n){v(this,4,t,f,n,arguments[2])},setUint32:function(t,n){v(this,4,t,f,n,arguments[2])},setFloat32:function(t,n){v(this,4,t,s,n,arguments[2])},setFloat64:function(t,n){v(this,8,t,a,n,arguments[2])}});j(N,F),j(T,A),b(T[I],g.VIEW,!0),n[F]=N,n[A]=T},function(t,n,r){var e=r(3),i=r(46),o=r(68),u=r(195),c=r(11).f;t.exports=function(t){var n=i.Symbol||(i.Symbol=o?{}:e.Symbol||{});"_"==t.charAt(0)||t in n||c(n,t,{value:u.f(t)})}},function(t,n,r){var e=r(81),i=r(7)("iterator"),o=r(82);t.exports=r(46).getIteratorMethod=function(t){if(null!=t)return t[i]||t["@@iterator"]||o[e(t)]}},function(t,n,r){"use strict";var e=r(67),i=r(178),o=r(82),u=r(33);t.exports=r(147)(Array,"Array",function(t,n){this._t=u(t),this._i=0,this._k=n},function(){var t=this._t,n=this._k,r=this._i++;return!t||r>=t.length?(this._t=void 0,i(1)):i(0,"keys"==n?r:"values"==n?t[r]:[r,t[r]])},"values"),o.Arguments=o.Array,e("keys"),e("values"),e("entries")},function(t,n){t.exports=function(t,n){t.classList?t.classList.add(n):t.className+=" "+n}},function(t,n){t.exports=function(t,n){if(t.classList)t.classList.remove(n);else{var r=new RegExp("(^|\\b)"+n.split(" ").join("|")+"(\\b|$)","gi");t.className=t.className.replace(r," ")}}},function(t,n,r){var e=r(45);t.exports=function(t,n){if("number"!=typeof t&&"Number"!=e(t))throw TypeError(n);return+t}},function(t,n,r){"use strict";var a=r(17),s=r(78),l=r(8);t.exports=[].copyWithin||function(t,n){var r=a(this),e=l(r.length),i=s(t,e),o=s(n,e),u=2<arguments.length?arguments[2]:void 0,c=Math.min((void 0===u?e:s(u,e))-o,e-i),f=1;for(o<i&&i<o+c&&(f=-1,o+=c-1,i+=c-1);0<c--;)o in r?r[i]=r[o]:delete r[i],i+=f,o+=f;return r}},function(t,n,r){var e=r(71);t.exports=function(t,n){var r=[];return e(t,!1,r.push,r,n),r}},function(t,n,r){var s=r(21),l=r(17),h=r(116),v=r(8);t.exports=function(t,n,r,e,i){s(n);var o=l(t),u=h(o),c=v(o.length),f=i?c-1:0,a=i?-1:1;if(r<2)for(;;){if(f in u){e=u[f],f+=a;break}if(f+=a,i?f<0:c<=f)throw TypeError("Reduce of empty array with no initial value")}for(;i?0<=f:f<c;f+=a)f in u&&(e=n(e,u[f],f,o));return e}},function(t,n,r){"use strict";var o=r(21),u=r(5),c=r(175),f=[].slice,a={};t.exports=Function.bind||function(n){var r=o(this),e=f.call(arguments,1),i=function(){var t=e.concat(f.call(arguments));return this instanceof i?function(t,n,r){if(!(n in a)){for(var e=[],i=0;i<n;i++)e[i]="a["+i+"]";a[n]=Function("F,a","return new F("+e.join(",")+")")}return a[n](t,r)}(r,t.length,t):c(r,t,n)};return u(r.prototype)&&(i.prototype=r.prototype),i}},function(t,n,r){"use strict";var u=r(11).f,c=r(72),f=r(76),a=r(47),s=r(70),l=r(71),e=r(147),i=r(178),o=r(77),h=r(10),v=r(69).fastKey,p=r(80),d=h?"_s":"size",y=function(t,n){var r,e=v(n);if("F"!==e)return t._i[e];for(r=t._f;r;r=r.n)if(r.k==n)return r};t.exports={getConstructor:function(t,o,r,e){var i=t(function(t,n){s(t,i,o,"_i"),t._t=o,t._i=c(null),t._f=void 0,t._l=void 0,t[d]=0,null!=n&&l(n,r,t[e],t)});return f(i.prototype,{clear:function(){for(var t=p(this,o),n=t._i,r=t._f;r;r=r.n)r.r=!0,r.p&&(r.p=r.p.n=void 0),delete n[r.i];t._f=t._l=void 0,t[d]=0},delete:function(t){var n=p(this,o),r=y(n,t);if(r){var e=r.n,i=r.p;delete n._i[r.i],r.r=!0,i&&(i.n=e),e&&(e.p=i),n._f==r&&(n._f=e),n._l==r&&(n._l=i),n[d]--}return!!r},forEach:function(t){p(this,o);for(var n,r=a(t,1<arguments.length?arguments[1]:void 0,3);n=n?n.n:this._f;)for(r(n.v,n.k,this);n&&n.r;)n=n.p},has:function(t){return!!y(p(this,o),t)}}),h&&u(i.prototype,"size",{get:function(){return p(this,o)[d]}}),i},def:function(t,n,r){var e,i,o=y(t,n);return o?o.v=r:(t._l=o={i:i=v(n,!0),k:n,v:r,p:e=t._l,n:void 0,r:!1},t._f||(t._f=o),e&&(e.n=o),t[d]++,"F"!==i&&(t._i[i]=o)),t},getEntry:y,setStrong:function(t,r,n){e(t,r,function(t,n){this._t=p(t,r),this._k=n,this._l=void 0},function(){for(var t=this,n=t._k,r=t._l;r&&r.r;)r=r.p;return t._t&&(t._l=r=r?r.n:t._t._f)?i(0,"keys"==n?r.k:"values"==n?r.v:[r.k,r.v]):(t._t=void 0,i(1))},n?"entries":"values",!n,!0),o(r)}}},function(t,n,r){var e=r(81),i=r(167);t.exports=function(t){return function(){if(e(this)!=t)throw TypeError(t+"#toJSON isn't generic");return i(this)}}},function(t,n,r){"use strict";var u=r(76),c=r(69).getWeak,i=r(2),f=r(5),a=r(70),s=r(71),e=r(50),l=r(30),h=r(80),o=e(5),v=e(6),p=0,d=function(t){return t._l||(t._l=new y)},y=function(){this.a=[]},g=function(t,n){return o(t.a,function(t){return t[0]===n})};y.prototype={get:function(t){var n=g(this,t);if(n)return n[1]},has:function(t){return!!g(this,t)},set:function(t,n){var r=g(this,t);r?r[1]=n:this.a.push([t,n])},delete:function(n){var t=v(this.a,function(t){return t[0]===n});return~t&&this.a.splice(t,1),!!~t}},t.exports={getConstructor:function(t,r,e,i){var o=t(function(t,n){a(t,o,r,"_i"),t._t=r,t._i=p++,t._l=void 0,null!=n&&s(n,e,t[i],t)});return u(o.prototype,{delete:function(t){if(!f(t))return!1;var n=c(t);return!0===n?d(h(this,r)).delete(t):n&&l(n,this._i)&&delete n[this._i]},has:function(t){if(!f(t))return!1;var n=c(t);return!0===n?d(h(this,r)).has(t):n&&l(n,this._i)}}),o},def:function(t,n,r){var e=c(i(n),!0);return!0===e?d(t).set(n,r):e[t._i]=r,t},ufstore:d}},function(t,n,r){"use strict";var p=r(123),d=r(5),y=r(8),g=r(47),b=r(7)("isConcatSpreadable");t.exports=function t(n,r,e,i,o,u,c,f){for(var a,s,l=o,h=0,v=!!c&&g(c,f,3);h<i;){if(h in e){if(a=v?v(e[h],h,r):e[h],s=!1,d(a)&&(s=void 0!==(s=a[b])?!!s:p(a)),s&&0<u)l=t(n,r,a,y(a.length),l,u-1)-1;else{if(9007199254740991<=l)throw TypeError();n[l]=a}l++}h++}return l}},function(t,n,r){t.exports=!r(10)&&!r(4)(function(){return 7!=Object.defineProperty(r(140)("div"),"a",{get:function(){return 7}}).a})},function(t,n){t.exports=function(t,n,r){var e=void 0===r;switch(n.length){case 0:return e?t():t.call(r);case 1:return e?t(n[0]):t.call(r,n[0]);case 2:return e?t(n[0],n[1]):t.call(r,n[0],n[1]);case 3:return e?t(n[0],n[1],n[2]):t.call(r,n[0],n[1],n[2]);case 4:return e?t(n[0],n[1],n[2],n[3]):t.call(r,n[0],n[1],n[2],n[3])}return t.apply(r,n)}},function(t,n,r){var e=r(5),i=Math.floor;t.exports=function(t){return!e(t)&&isFinite(t)&&i(t)===t}},function(t,n,r){var o=r(2);t.exports=function(t,n,r,e){try{return e?n(o(r)[0],r[1]):n(r)}catch(n){var i=t.return;throw void 0!==i&&o(i.call(t)),n}}},function(t,n){t.exports=function(t,n){return{value:n,done:!!t}}},function(t,n,r){var o=r(149),e=Math.pow,u=e(2,-52),c=e(2,-23),f=e(2,127)*(2-c),a=e(2,-126);t.exports=Math.fround||function(t){var n,r,e=Math.abs(t),i=o(t);return e<a?i*(e/a/c+1/u-1/u)*a*c:f<(r=(n=(1+c/u)*e)-(n-e))||r!=r?i*(1/0):i*r}},function(t,n){t.exports=Math.log1p||function(t){return-1e-8<(t=+t)&&t<1e-8?t-t*t/2:Math.log(1+t)}},function(t,n){t.exports=Math.scale||function(t,n,r,e,i){return 0===arguments.length||t!=t||n!=n||r!=r||e!=e||i!=i?NaN:t===1/0||t===-1/0?t:(t-n)*(i-e)/(r-n)+e}},function(t,n,r){"use strict";var h=r(10),v=r(74),p=r(127),d=r(117),y=r(17),g=r(116),i=Object.assign;t.exports=!i||r(4)(function(){var t={},n={},r=Symbol(),e="abcdefghijklmnopqrst";return t[r]=7,e.split("").forEach(function(t){n[t]=t}),7!=i({},t)[r]||Object.keys(i({},n)).join("")!=e})?function(t,n){for(var r=y(t),e=arguments.length,i=1,o=p.f,u=d.f;i<e;)for(var c,f=g(arguments[i++]),a=o?v(f).concat(o(f)):v(f),s=a.length,l=0;l<s;)c=a[l++],h&&!u.call(f,c)||(r[c]=f[c]);return r}:i},function(t,n,r){var u=r(11),c=r(2),f=r(74);t.exports=r(10)?Object.defineProperties:function(t,n){c(t);for(var r,e=f(n),i=e.length,o=0;o<i;)u.f(t,r=e[o++],n[r]);return t}},function(t,n,r){var e=r(33),i=r(73).f,o={}.toString,u="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];t.exports.f=function(t){return u&&"[object Window]"==o.call(t)?function(t){try{return i(t)}catch(t){return u.slice()}}(t):i(e(t))}},function(t,n,r){var u=r(30),c=r(33),f=r(120)(!1),a=r(154)("IE_PROTO");t.exports=function(t,n){var r,e=c(t),i=0,o=[];for(r in e)r!=a&&u(e,r)&&o.push(r);for(;n.length>i;)u(e,r=n[i++])&&(~f(o,r)||o.push(r));return o}},function(t,n,r){var f=r(10),a=r(74),s=r(33),l=r(117).f;t.exports=function(c){return function(t){for(var n,r=s(t),e=a(r),i=e.length,o=0,u=[];o<i;)n=e[o++],f&&!l.call(r,n)||u.push(c?[n,r[n]]:r[n]);return u}}},function(t,n,r){var e=r(73),i=r(127),o=r(2),u=r(3).Reflect;t.exports=u&&u.ownKeys||function(t){var n=e.f(o(t)),r=i.f;return r?n.concat(r(t)):n}},function(t,n,r){var e=r(3).parseFloat,i=r(84).trim;t.exports=1/e(r(157)+"-0")!=-1/0?function(t){var n=i(String(t),3),r=e(n);return 0===r&&"-"==n.charAt(0)?-0:r}:e},function(t,n,r){var e=r(3).parseInt,i=r(84).trim,o=r(157),u=/^[-+]?0[xX]/;t.exports=8!==e(o+"08")||22!==e(o+"0x16")?function(t,n){var r=i(String(t),3);return e(r,n>>>0||(u.test(r)?16:10))}:e},function(t,n){t.exports=function(t){try{return{e:!1,v:t()}}catch(t){return{e:!0,v:t}}}},function(t,n,r){var e=r(2),i=r(5),o=r(151);t.exports=function(t,n){if(e(t),i(n)&&n.constructor===t)return n;var r=o.f(t);return(0,r.resolve)(n),r.promise}},function(t,n){t.exports=Object.is||function(t,n){return t===n?0!==t||1/t==1/n:t!=t&&n!=n}},function(t,n,r){var s=r(8),l=r(156),h=r(51);t.exports=function(t,n,r,e){var i=String(h(t)),o=i.length,u=void 0===r?" ":String(r),c=s(n);if(c<=o||""==u)return i;var f=c-o,a=l.call(u,Math.ceil(f/u.length));return a.length>f&&(a=a.slice(0,f)),e?a+i:i+a}},function(t,n,r){var e=r(49),i=r(8);t.exports=function(t){if(void 0===t)return 0;var n=e(t),r=i(n);if(n!==r)throw RangeError("Wrong length!");return r}},function(t,n,r){n.f=r(7)},function(t,n,r){"use strict";var e=r(170),i=r(80);t.exports=r(121)("Map",function(t){return function(){return t(this,0<arguments.length?arguments[0]:void 0)}},{get:function(t){var n=e.getEntry(i(this,"Map"),t);return n&&n.v},set:function(t,n){return e.def(i(this,"Map"),0===t?0:t,n)}},e,!0)},function(t,n,r){"use strict";var e=r(152);r(1)({target:"RegExp",proto:!0,forced:e!==/./.exec},{exec:e})},function(t,n,r){r(10)&&"g"!=/./g.flags&&r(11).f(RegExp.prototype,"flags",{configurable:!0,get:r(115)})},function(t,n,r){"use strict";var e=r(170),i=r(80);t.exports=r(121)("Set",function(t){return function(){return t(this,0<arguments.length?arguments[0]:void 0)}},{add:function(t){return e.def(i(this,"Set"),t=0===t?0:t,t)}},e)},function(t,n,r){"use strict";var o,e=r(3),i=r(50)(0),u=r(27),c=r(69),f=r(182),a=r(172),s=r(5),l=r(80),h=r(80),v=!e.ActiveXObject&&"ActiveXObject"in e,p="WeakMap",d=c.getWeak,y=Object.isExtensible,g=a.ufstore,b=function(t){return function(){return t(this,0<arguments.length?arguments[0]:void 0)}},x={get:function(t){if(s(t)){var n=d(t);return!0===n?g(l(this,p)).get(t):n?n[this._i]:void 0}},set:function(t,n){return a.def(l(this,p),t,n)}},m=t.exports=r(121)(p,b,x,a,!0,!0);h&&v&&(f((o=a.getConstructor(b,p)).prototype,x),c.NEED=!0,i(["delete","has","get","set"],function(e){var t=m.prototype,i=t[e];u(t,e,function(t,n){if(!s(t)||y(t))return i.call(this,t,n);this._f||(this._f=new o);var r=this._f[e](t,n);return"set"==e?this:r})}))},,,,function(t,n){"use strict";t.exports={init:function(){var t=document.querySelector("#page-nav");t&&!document.querySelector("#page-nav .extend.prev")&&(t.innerHTML='<a class="extend prev disabled" rel="prev">&laquo; Prev</a>'+t.innerHTML),t&&!document.querySelector("#page-nav .extend.next")&&(t.innerHTML=t.innerHTML+'<a class="extend next disabled" rel="next">Next &raquo;</a>'),yiliaConfig&&yiliaConfig.open_in_new&&document.querySelectorAll(".article-entry a:not(.article-more-a)").forEach(function(t){var n=t.getAttribute("target");n&&""!==n||t.setAttribute("target","_blank")}),yiliaConfig&&yiliaConfig.toc_hide_index&&document.querySelectorAll(".toc-number").forEach(function(t){t.style.display="none"})}}},function(t,n,r){"use strict";function e(t){return t&&t.__esModule?t:{default:t}}function i(t,n,r,e,i){var o=function(t){for(var n=t.offsetLeft,r=t.offsetParent;null!==r;)n+=r.offsetLeft,r=r.offsetParent;return n}(t),u=function(t){for(var n=t.offsetTop,r=t.offsetParent;null!==r;)n+=r.offsetTop,r=r.offsetParent;return n}(t)-n;if(u-r<=i){var c=t.$newDom;c||(c=t.cloneNode(!0),(0,a.default)(t,c),(t.$newDom=c).style.position="fixed",c.style.top=(r||u)+"px",c.style.left=o+"px",c.style.zIndex=e||2,c.style.width="100%",c.style.color="#fff"),c.style.visibility="visible",t.style.visibility="hidden"}else{t.style.visibility="visible";var f=t.$newDom;f&&(f.style.visibility="hidden")}}function o(){var t=document.querySelector(".js-overlay"),n=document.querySelector(".js-header-menu");i(t,document.body.scrollTop,-63,2,0),i(n,document.body.scrollTop,1,3,0)}var f=e(r(163)),a=e((e(r(164)),r(414))),u=e(r(134)),c=e(r(204)),s=r(135);u.default.versions.mobile&&window.screen.width<800&&(function(){for(var t=document.querySelectorAll(".js-header-menu li a"),n=window.location.pathname,r=0,e=t.length;r<e;r++){var i=t[r];o=n,u=i.getAttribute("href"),c=/\/|index.html/g,o.replace(c,"")===u.replace(c,"")&&(0,f.default)(i,"active")}var o,u,c}(),document.querySelector("#container").addEventListener("scroll",function(t){o()}),window.addEventListener("scroll",function(t){o()}),o()),(0,s.addLoadEvent)(function(){c.default.init()}),t.exports={}},,,function(t,n,r){(function(t){"use strict";function n(t,n,r){t[n]||Object.defineProperty(t,n,{writable:!0,configurable:!0,value:r})}if(r(413),r(209),r(211),t._babelPolyfill)throw new Error("only one instance of babel-polyfill is allowed");t._babelPolyfill=!0;n(String.prototype,"padLeft","".padStart),n(String.prototype,"padRight","".padEnd),"pop,reverse,shift,keys,values,entries,indexOf,every,some,forEach,map,filter,find,findIndex,includes,join,slice,concat,push,splice,unshift,sort,lastIndexOf,reduce,reduceRight,copyWithin,fill".split(",").forEach(function(t){[][t]&&n(Array,t,Function.call.bind([][t]))})}).call(n,function(){return this}())},function(L,t){(function(t){!function(t){"use strict";function o(t,n,r,e){var o,u,c,f,i=n&&n.prototype instanceof h?n:h,a=Object.create(i.prototype),s=new p(e||[]);return a._invoke=(o=t,u=r,c=s,f=_,function(t,n){if(f===E)throw new Error("Generator is already running");if(f===M){if("throw"===t)throw n;return d()}for(c.method=t,c.arg=n;;){var r=c.delegate;if(r){var e=v(r,c);if(e){if(e===P)continue;return e}}if("next"===c.method)c.sent=c._sent=c.arg;else if("throw"===c.method){if(f===_)throw f=M,c.arg;c.dispatchException(c.arg)}else"return"===c.method&&c.abrupt("return",c.arg);f=E;var i=l(o,u,c);if("normal"===i.type){if(f=c.done?M:O,i.arg===P)continue;return{value:i.arg,done:c.done}}"throw"===i.type&&(f=M,c.method="throw",c.arg=i.arg)}}),a}function l(t,n,r){try{return{type:"normal",arg:t.call(n,r)}}catch(t){return{type:"throw",arg:t}}}function h(){}function r(){}function n(){}function e(t){["next","throw","return"].forEach(function(n){t[n]=function(t){return this._invoke(n,t)}})}function u(c){function f(t,n,r,e){var i=l(c[t],c,n);if("throw"!==i.type){var o=i.arg,u=o.value;return u&&"object"==typeof u&&y.call(u,"__await")?Promise.resolve(u.__await).then(function(t){f("next",t,r,e)},function(t){f("throw",t,r,e)}):Promise.resolve(u).then(function(t){o.value=t,r(o)},e)}e(i.arg)}var n;"object"==typeof t.process&&t.process.domain&&(f=t.process.domain.bind(f)),this._invoke=function(r,e){function t(){return new Promise(function(t,n){f(r,e,t,n)})}return n=n?n.then(t,t):t()}}function v(t,n){var r=t.iterator[n.method];if(r===a){if(n.delegate=null,"throw"===n.method){if(t.iterator.return&&(n.method="return",n.arg=a,v(t,n),"throw"===n.method))return P;n.method="throw",n.arg=new TypeError("The iterator does not provide a 'throw' method")}return P}var e=l(r,t.iterator,n.arg);if("throw"===e.type)return n.method="throw",n.arg=e.arg,n.delegate=null,P;var i=e.arg;return i?i.done?(n[t.resultName]=i.value,n.next=t.nextLoc,"return"!==n.method&&(n.method="next",n.arg=a),n.delegate=null,P):i:(n.method="throw",n.arg=new TypeError("iterator result is not an object"),n.delegate=null,P)}function i(t){var n={tryLoc:t[0]};1 in t&&(n.catchLoc=t[1]),2 in t&&(n.finallyLoc=t[2],n.afterLoc=t[3]),this.tryEntries.push(n)}function c(t){var n=t.completion||{};n.type="normal",delete n.arg,t.completion=n}function p(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(i,this),this.reset(!0)}function f(n){if(n){var t=n[b];if(t)return t.call(n);if("function"==typeof n.next)return n;if(!isNaN(n.length)){var r=-1,e=function t(){for(;++r<n.length;)if(y.call(n,r))return t.value=n[r],t.done=!1,t;return t.value=a,t.done=!0,t};return e.next=e}}return{next:d}}function d(){return{value:a,done:!0}}var a,s=Object.prototype,y=s.hasOwnProperty,g="function"==typeof Symbol?Symbol:{},b=g.iterator||"@@iterator",x=g.asyncIterator||"@@asyncIterator",m=g.toStringTag||"@@toStringTag",S="object"==typeof L,w=t.regeneratorRuntime;if(w)S&&(L.exports=w);else{(w=t.regeneratorRuntime=S?L.exports:{}).wrap=o;var _="suspendedStart",O="suspendedYield",E="executing",M="completed",P={},j={};j[b]=function(){return this};var F=Object.getPrototypeOf,A=F&&F(F(f([])));A&&A!==s&&y.call(A,b)&&(j=A);var I=n.prototype=h.prototype=Object.create(j);r.prototype=I.constructor=n,n.constructor=r,n[m]=r.displayName="GeneratorFunction",w.isGeneratorFunction=function(t){var n="function"==typeof t&&t.constructor;return!!n&&(n===r||"GeneratorFunction"===(n.displayName||n.name))},w.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,n):(t.__proto__=n,m in t||(t[m]="GeneratorFunction")),t.prototype=Object.create(I),t},w.awrap=function(t){return{__await:t}},e(u.prototype),u.prototype[x]=function(){return this},w.AsyncIterator=u,w.async=function(t,n,r,e){var i=new u(o(t,n,r,e));return w.isGeneratorFunction(n)?i:i.next().then(function(t){return t.done?t.value:i.next()})},e(I),I[m]="Generator",I[b]=function(){return this},I.toString=function(){return"[object Generator]"},w.keys=function(r){var e=[];for(var t in r)e.push(t);return e.reverse(),function t(){for(;e.length;){var n=e.pop();if(n in r)return t.value=n,t.done=!1,t}return t.done=!0,t}},w.values=f,p.prototype={constructor:p,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=a,this.done=!1,this.delegate=null,this.method="next",this.arg=a,this.tryEntries.forEach(c),!t)for(var n in this)"t"===n.charAt(0)&&y.call(this,n)&&!isNaN(+n.slice(1))&&(this[n]=a)},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(r){function t(t,n){return o.type="throw",o.arg=r,e.next=t,n&&(e.method="next",e.arg=a),!!n}if(this.done)throw r;for(var e=this,n=this.tryEntries.length-1;0<=n;--n){var i=this.tryEntries[n],o=i.completion;if("root"===i.tryLoc)return t("end");if(i.tryLoc<=this.prev){var u=y.call(i,"catchLoc"),c=y.call(i,"finallyLoc");if(u&&c){if(this.prev<i.catchLoc)return t(i.catchLoc,!0);if(this.prev<i.finallyLoc)return t(i.finallyLoc)}else if(u){if(this.prev<i.catchLoc)return t(i.catchLoc,!0)}else{if(!c)throw new Error("try statement without catch or finally");if(this.prev<i.finallyLoc)return t(i.finallyLoc)}}}},abrupt:function(t,n){for(var r=this.tryEntries.length-1;0<=r;--r){var e=this.tryEntries[r];if(e.tryLoc<=this.prev&&y.call(e,"finallyLoc")&&this.prev<e.finallyLoc){var i=e;break}}i&&("break"===t||"continue"===t)&&i.tryLoc<=n&&n<=i.finallyLoc&&(i=null);var o=i?i.completion:{};return o.type=t,o.arg=n,i?(this.method="next",this.next=i.finallyLoc,P):this.complete(o)},complete:function(t,n){if("throw"===t.type)throw t.arg;return"break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&n&&(this.next=n),P},finish:function(t){for(var n=this.tryEntries.length-1;0<=n;--n){var r=this.tryEntries[n];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),c(r),P}},catch:function(t){for(var n=this.tryEntries.length-1;0<=n;--n){var r=this.tryEntries[n];if(r.tryLoc===t){var e=r.completion;if("throw"===e.type){var i=e.arg;c(r)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(t,n,r){return this.delegate={iterator:f(t),resultName:n,nextLoc:r},"next"===this.method&&(this.arg=a),P}}}}("object"==typeof t?t:"object"==typeof window?window:"object"==typeof self?self:this)}).call(t,function(){return this}())},,function(t,n,r){r(221),t.exports=r(46).RegExp.escape},,,,function(t,n,r){var e=r(5),i=r(123),o=r(7)("species");t.exports=function(t){var n;return i(t)&&("function"!=typeof(n=t.constructor)||n!==Array&&!i(n.prototype)||(n=void 0),e(n)&&(null===(n=n[o])&&(n=void 0))),void 0===n?Array:n}},function(t,n,r){"use strict";var e=r(4),i=Date.prototype.getTime,o=Date.prototype.toISOString,u=function(t){return 9<t?t:"0"+t};t.exports=e(function(){return"0385-07-25T07:06:39.999Z"!=o.call(new Date(-5e13-1))})||!e(function(){o.call(new Date(NaN))})?function(){if(!isFinite(i.call(this)))throw RangeError("Invalid time value");var t=this,n=t.getUTCFullYear(),r=t.getUTCMilliseconds(),e=n<0?"-":9999<n?"+":"";return e+("00000"+Math.abs(n)).slice(e?-6:-4)+"-"+u(t.getUTCMonth()+1)+"-"+u(t.getUTCDate())+"T"+u(t.getUTCHours())+":"+u(t.getUTCMinutes())+":"+u(t.getUTCSeconds())+"."+(99<r?r:"0"+u(r))+"Z"}:o},function(t,n,r){"use strict";var e=r(2),i=r(53);t.exports=function(t){if("string"!==t&&"number"!==t&&"default"!==t)throw TypeError("Incorrect hint");return i(e(this),"number"!=t)}},function(t,n,r){var c=r(74),f=r(127),a=r(117);t.exports=function(t){var n=c(t),r=f.f;if(r)for(var e,i=r(t),o=a.f,u=0;i.length>u;)o.call(t,e=i[u++])&&n.push(e);return n}},function(t,n,r){t.exports=r(118)("native-function-to-string",Function.toString)},function(t,n){t.exports=function(n,r){var e=r===Object(r)?function(t){return r[t]}:r;return function(t){return String(t).replace(n,e)}}},function(t,n,r){var e=r(1),i=r(220)(/[\\^$*+?.()|[\]{}]/g,"\\$&");e(e.S,"RegExp",{escape:function(t){return i(t)}})},function(t,n,r){var e=r(1);e(e.P,"Array",{copyWithin:r(166)}),r(67)("copyWithin")},function(t,n,r){"use strict";var e=r(1),i=r(50)(4);e(e.P+e.F*!r(48)([].every,!0),"Array",{every:function(t){return i(this,t,arguments[1])}})},function(t,n,r){var e=r(1);e(e.P,"Array",{fill:r(137)}),r(67)("fill")},function(t,n,r){"use strict";var e=r(1),i=r(50)(2);e(e.P+e.F*!r(48)([].filter,!0),"Array",{filter:function(t){return i(this,t,arguments[1])}})},function(t,n,r){"use strict";var e=r(1),i=r(50)(6),o="findIndex",u=!0;o in[]&&Array(1)[o](function(){u=!1}),e(e.P+e.F*u,"Array",{findIndex:function(t){return i(this,t,1<arguments.length?arguments[1]:void 0)}}),r(67)(o)},function(t,n,r){"use strict";var e=r(1),i=r(50)(5),o="find",u=!0;o in[]&&Array(1)[o](function(){u=!1}),e(e.P+e.F*u,"Array",{find:function(t){return i(this,t,1<arguments.length?arguments[1]:void 0)}}),r(67)(o)},function(t,n,r){"use strict";var e=r(1),i=r(50)(0),o=r(48)([].forEach,!0);e(e.P+e.F*!o,"Array",{forEach:function(t){return i(this,t,arguments[1])}})},function(t,n,r){"use strict";var h=r(47),e=r(1),v=r(17),p=r(177),d=r(145),y=r(8),g=r(139),b=r(161);e(e.S+e.F*!r(125)(function(t){Array.from(t)}),"Array",{from:function(t){var n,r,e,i,o=v(t),u="function"==typeof this?this:Array,c=arguments.length,f=1<c?arguments[1]:void 0,a=void 0!==f,s=0,l=b(o);if(a&&(f=h(f,2<c?arguments[2]:void 0,2)),null==l||u==Array&&d(l))for(r=new u(n=y(o.length));s<n;s++)g(r,s,a?f(o[s],s):o[s]);else for(i=l.call(o),r=new u;!(e=i.next()).done;s++)g(r,s,a?p(i,f,[e.value,s],!0):e.value);return r.length=s,r}})},function(t,n,r){"use strict";var e=r(1),i=r(120)(!1),o=[].indexOf,u=!!o&&1/[1].indexOf(1,-0)<0;e(e.P+e.F*(u||!r(48)(o)),"Array",{indexOf:function(t){return u?o.apply(this,arguments)||0:i(this,t,arguments[1])}})},function(t,n,r){var e=r(1);e(e.S,"Array",{isArray:r(123)})},function(t,n,r){"use strict";var e=r(1),i=r(33),o=[].join;e(e.P+e.F*(r(116)!=Object||!r(48)(o)),"Array",{join:function(t){return o.call(i(this),void 0===t?",":t)}})},function(t,n,r){"use strict";var e=r(1),i=r(33),o=r(49),u=r(8),c=[].lastIndexOf,f=!!c&&1/[1].lastIndexOf(1,-0)<0;e(e.P+e.F*(f||!r(48)(c)),"Array",{lastIndexOf:function(t){if(f)return c.apply(this,arguments)||0;var n=i(this),r=u(n.length),e=r-1;for(1<arguments.length&&(e=Math.min(e,o(arguments[1]))),e<0&&(e=r+e);0<=e;e--)if(e in n&&n[e]===t)return e||0;return-1}})},function(t,n,r){"use strict";var e=r(1),i=r(50)(1);e(e.P+e.F*!r(48)([].map,!0),"Array",{map:function(t){return i(this,t,arguments[1])}})},function(t,n,r){"use strict";var e=r(1),i=r(139);e(e.S+e.F*r(4)(function(){function t(){}return!(Array.of.call(t)instanceof t)}),"Array",{of:function(){for(var t=0,n=arguments.length,r=new("function"==typeof this?this:Array)(n);t<n;)i(r,t,arguments[t++]);return r.length=n,r}})},function(t,n,r){"use strict";var e=r(1),i=r(168);e(e.P+e.F*!r(48)([].reduceRight,!0),"Array",{reduceRight:function(t){return i(this,t,arguments.length,arguments[1],!0)}})},function(t,n,r){"use strict";var e=r(1),i=r(168);e(e.P+e.F*!r(48)([].reduce,!0),"Array",{reduce:function(t){return i(this,t,arguments.length,arguments[1],!1)}})},function(t,n,r){"use strict";var e=r(1),i=r(143),a=r(45),s=r(78),l=r(8),h=[].slice;e(e.P+e.F*r(4)(function(){i&&h.call(i)}),"Array",{slice:function(t,n){var r=l(this.length),e=a(this);if(n=void 0===n?r:n,"Array"==e)return h.call(this,t,n);for(var i=s(t,r),o=s(n,r),u=l(o-i),c=new Array(u),f=0;f<u;f++)c[f]="String"==e?this.charAt(i+f):this[i+f];return c}})},function(t,n,r){"use strict";var e=r(1),i=r(50)(3);e(e.P+e.F*!r(48)([].some,!0),"Array",{some:function(t){return i(this,t,arguments[1])}})},function(t,n,r){"use strict";var e=r(1),i=r(21),o=r(17),u=r(4),c=[].sort,f=[1,2,3];e(e.P+e.F*(u(function(){f.sort(void 0)})||!u(function(){f.sort(null)})||!r(48)(c)),"Array",{sort:function(t){return void 0===t?c.call(o(this)):c.call(o(this),i(t))}})},function(t,n,r){r(77)("Array")},function(t,n,r){var e=r(1);e(e.S,"Date",{now:function(){return(new Date).getTime()}})},function(t,n,r){var e=r(1),i=r(216);e(e.P+e.F*(Date.prototype.toISOString!==i),"Date",{toISOString:i})},function(t,n,r){"use strict";var e=r(1),i=r(17),o=r(53);e(e.P+e.F*r(4)(function(){return null!==new Date(NaN).toJSON()||1!==Date.prototype.toJSON.call({toISOString:function(){return 1}})}),"Date",{toJSON:function(t){var n=i(this),r=o(n);return"number"!=typeof r||isFinite(r)?n.toISOString():null}})},function(t,n,r){var e=r(7)("toPrimitive"),i=Date.prototype;e in i||r(26)(i,e,r(217))},function(t,n,r){var e=Date.prototype,i="Invalid Date",o="toString",u=e[o],c=e.getTime;new Date(NaN)+""!=i&&r(27)(e,o,function(){var t=c.call(this);return t==t?u.call(this):i})},function(t,n,r){var e=r(1);e(e.P,"Function",{bind:r(169)})},function(t,n,r){"use strict";var e=r(5),i=r(32),o=r(7)("hasInstance"),u=Function.prototype;o in u||r(11).f(u,o,{value:function(t){if("function"!=typeof this||!e(t))return!1;if(!e(this.prototype))return t instanceof this;for(;t=i(t);)if(this.prototype===t)return!0;return!1}})},function(t,n,r){var e=r(11).f,i=Function.prototype,o=/^\s*function ([^ (]*)/;"name"in i||r(10)&&e(i,"name",{configurable:!0,get:function(){try{return(""+this).match(o)[1]}catch(t){return""}}})},function(t,n,r){var e=r(1),i=r(180),o=Math.sqrt,u=Math.acosh;e(e.S+e.F*!(u&&710==Math.floor(u(Number.MAX_VALUE))&&u(1/0)==1/0),"Math",{acosh:function(t){return(t=+t)<1?NaN:94906265.62425156<t?Math.log(t)+Math.LN2:i(t-1+o(t-1)*o(t+1))}})},function(t,n,r){var e=r(1),i=Math.asinh;e(e.S+e.F*!(i&&0<1/i(0)),"Math",{asinh:function t(n){return isFinite(n=+n)&&0!=n?n<0?-t(-n):Math.log(n+Math.sqrt(n*n+1)):n}})},function(t,n,r){var e=r(1),i=Math.atanh;e(e.S+e.F*!(i&&1/i(-0)<0),"Math",{atanh:function(t){return 0==(t=+t)?t:Math.log((1+t)/(1-t))/2}})},function(t,n,r){var e=r(1),i=r(149);e(e.S,"Math",{cbrt:function(t){return i(t=+t)*Math.pow(Math.abs(t),1/3)}})},function(t,n,r){var e=r(1);e(e.S,"Math",{clz32:function(t){return(t>>>=0)?31-Math.floor(Math.log(t+.5)*Math.LOG2E):32}})},function(t,n,r){var e=r(1),i=Math.exp;e(e.S,"Math",{cosh:function(t){return(i(t=+t)+i(-t))/2}})},function(t,n,r){var e=r(1),i=r(148);e(e.S+e.F*(i!=Math.expm1),"Math",{expm1:i})},function(t,n,r){var e=r(1);e(e.S,"Math",{fround:r(179)})},function(t,n,r){var e=r(1),f=Math.abs;e(e.S,"Math",{hypot:function(t,n){for(var r,e,i=0,o=0,u=arguments.length,c=0;o<u;)c<(r=f(arguments[o++]))?(i=i*(e=c/r)*e+1,c=r):0<r?i+=(e=r/c)*e:i+=r;return c===1/0?1/0:c*Math.sqrt(i)}})},function(t,n,r){var e=r(1),i=Math.imul;e(e.S+e.F*r(4)(function(){return-5!=i(4294967295,5)||2!=i.length}),"Math",{imul:function(t,n){var r=65535,e=+t,i=+n,o=r&e,u=r&i;return 0|o*u+((r&e>>>16)*u+o*(r&i>>>16)<<16>>>0)}})},function(t,n,r){var e=r(1);e(e.S,"Math",{log10:function(t){return Math.log(t)*Math.LOG10E}})},function(t,n,r){var e=r(1);e(e.S,"Math",{log1p:r(180)})},function(t,n,r){var e=r(1);e(e.S,"Math",{log2:function(t){return Math.log(t)/Math.LN2}})},function(t,n,r){var e=r(1);e(e.S,"Math",{sign:r(149)})},function(t,n,r){var e=r(1),i=r(148),o=Math.exp;e(e.S+e.F*r(4)(function(){return-2e-17!=!Math.sinh(-2e-17)}),"Math",{sinh:function(t){return Math.abs(t=+t)<1?(i(t)-i(-t))/2:(o(t-1)-o(-t-1))*(Math.E/2)}})},function(t,n,r){var e=r(1),i=r(148),o=Math.exp;e(e.S,"Math",{tanh:function(t){var n=i(t=+t),r=i(-t);return n==1/0?1:r==1/0?-1:(n-r)/(o(t)+o(-t))}})},function(t,n,r){var e=r(1);e(e.S,"Math",{trunc:function(t){return(0<t?Math.floor:Math.ceil)(t)}})},function(t,n,r){"use strict";var e=r(3),i=r(30),o=r(45),u=r(144),s=r(53),c=r(4),f=r(73).f,a=r(31).f,l=r(11).f,h=r(84).trim,v="Number",p=e[v],d=p,y=p.prototype,g=o(r(72)(y))==v,b="trim"in String.prototype,x=function(t){var n=s(t,!1);if("string"==typeof n&&2<n.length){var r,e,i,o=(n=b?n.trim():h(n,3)).charCodeAt(0);if(43===o||45===o){if(88===(r=n.charCodeAt(2))||120===r)return NaN}else if(48===o){switch(n.charCodeAt(1)){case 66:case 98:e=2,i=49;break;case 79:case 111:e=8,i=55;break;default:return+n}for(var u,c=n.slice(2),f=0,a=c.length;f<a;f++)if((u=c.charCodeAt(f))<48||i<u)return NaN;return parseInt(c,e)}}return+n};if(!p(" 0o1")||!p("0b1")||p("+0x1")){p=function(t){var n=arguments.length<1?0:t,r=this;return r instanceof p&&(g?c(function(){y.valueOf.call(r)}):o(r)!=v)?u(new d(x(n)),r,p):x(n)};for(var m,S=r(10)?f(d):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger".split(","),w=0;S.length>w;w++)i(d,m=S[w])&&!i(p,m)&&l(p,m,a(d,m));(p.prototype=y).constructor=p,r(27)(e,v,p)}},function(t,n,r){var e=r(1);e(e.S,"Number",{EPSILON:Math.pow(2,-52)})},function(t,n,r){var e=r(1),i=r(3).isFinite;e(e.S,"Number",{isFinite:function(t){return"number"==typeof t&&i(t)}})},function(t,n,r){var e=r(1);e(e.S,"Number",{isInteger:r(176)})},function(t,n,r){var e=r(1);e(e.S,"Number",{isNaN:function(t){return t!=t}})},function(t,n,r){var e=r(1),i=r(176),o=Math.abs;e(e.S,"Number",{isSafeInteger:function(t){return i(t)&&o(t)<=9007199254740991}})},function(t,n,r){var e=r(1);e(e.S,"Number",{MAX_SAFE_INTEGER:9007199254740991})},function(t,n,r){var e=r(1);e(e.S,"Number",{MIN_SAFE_INTEGER:-9007199254740991})},function(t,n,r){var e=r(1),i=r(188);e(e.S+e.F*(Number.parseFloat!=i),"Number",{parseFloat:i})},function(t,n,r){var e=r(1),i=r(189);e(e.S+e.F*(Number.parseInt!=i),"Number",{parseInt:i})},function(t,n,r){"use strict";var e=r(1),a=r(49),s=r(165),l=r(156),i=1..toFixed,o=Math.floor,u=[0,0,0,0,0,0],h="Number.toFixed: incorrect invocation!",v=function(t,n){for(var r=-1,e=n;++r<6;)e+=t*u[r],u[r]=e%1e7,e=o(e/1e7)},p=function(t){for(var n=6,r=0;0<=--n;)r+=u[n],u[n]=o(r/t),r=r%t*1e7},d=function(){for(var t=6,n="";0<=--t;)if(""!==n||0===t||0!==u[t]){var r=String(u[t]);n=""===n?r:n+l.call("0",7-r.length)+r}return n},y=function(t,n,r){return 0===n?r:n%2==1?y(t,n-1,r*t):y(t*t,n/2,r)};e(e.P+e.F*(!!i&&("0.000"!==8e-5.toFixed(3)||"1"!==.9.toFixed(0)||"1.25"!==1.255.toFixed(2)||"1000000000000000128"!==(0xde0b6b3a7640080).toFixed(0))||!r(4)(function(){i.call({})})),"Number",{toFixed:function(t){var n,r,e,i,o=s(this,h),u=a(t),c="",f="0";if(u<0||20<u)throw RangeError(h);if(o!=o)return"NaN";if(o<=-1e21||1e21<=o)return String(o);if(o<0&&(c="-",o=-o),1e-21<o)if(r=(n=function(t){for(var n=0,r=t;4096<=r;)n+=12,r/=4096;for(;2<=r;)n+=1,r/=2;return n}(o*y(2,69,1))-69)<0?o*y(2,-n,1):o/y(2,n,1),r*=4503599627370496,0<(n=52-n)){for(v(0,r),e=u;7<=e;)v(1e7,0),e-=7;for(v(y(10,e,1),0),e=n-1;23<=e;)p(1<<23),e-=23;p(1<<e),v(1,1),p(2),f=d()}else v(0,r),v(1<<-n,0),f=d()+l.call("0",u);return f=0<u?c+((i=f.length)<=u?"0."+l.call("0",u-i)+f:f.slice(0,i-u)+"."+f.slice(i-u)):c+f}})},function(t,n,r){"use strict";var e=r(1),i=r(4),o=r(165),u=1..toPrecision;e(e.P+e.F*(i(function(){return"1"!==u.call(1,void 0)})||!i(function(){u.call({})})),"Number",{toPrecision:function(t){var n=o(this,"Number#toPrecision: incorrect invocation!");return void 0===t?u.call(n):u.call(n,t)}})},function(t,n,r){var e=r(1);e(e.S+e.F,"Object",{assign:r(182)})},function(t,n,r){var e=r(1);e(e.S,"Object",{create:r(72)})},function(t,n,r){var e=r(1);e(e.S+e.F*!r(10),"Object",{defineProperties:r(183)})},function(t,n,r){var e=r(1);e(e.S+e.F*!r(10),"Object",{defineProperty:r(11).f})},function(t,n,r){var e=r(5),i=r(69).onFreeze;r(52)("freeze",function(n){return function(t){return n&&e(t)?n(i(t)):t}})},function(t,n,r){var e=r(33),i=r(31).f;r(52)("getOwnPropertyDescriptor",function(){return function(t,n){return i(e(t),n)}})},function(t,n,r){r(52)("getOwnPropertyNames",function(){return r(184).f})},function(t,n,r){var e=r(17),i=r(32);r(52)("getPrototypeOf",function(){return function(t){return i(e(t))}})},function(t,n,r){var e=r(5);r(52)("isExtensible",function(n){return function(t){return!!e(t)&&(!n||n(t))}})},function(t,n,r){var e=r(5);r(52)("isFrozen",function(n){return function(t){return!e(t)||!!n&&n(t)}})},function(t,n,r){var e=r(5);r(52)("isSealed",function(n){return function(t){return!e(t)||!!n&&n(t)}})},function(t,n,r){var e=r(1);e(e.S,"Object",{is:r(192)})},function(t,n,r){var e=r(17),i=r(74);r(52)("keys",function(){return function(t){return i(e(t))}})},function(t,n,r){var e=r(5),i=r(69).onFreeze;r(52)("preventExtensions",function(n){return function(t){return n&&e(t)?n(i(t)):t}})},function(t,n,r){var e=r(5),i=r(69).onFreeze;r(52)("seal",function(n){return function(t){return n&&e(t)?n(i(t)):t}})},function(t,n,r){var e=r(1);e(e.S,"Object",{setPrototypeOf:r(153).set})},function(t,n,r){"use strict";var e=r(81),i={};i[r(7)("toStringTag")]="z",i+""!="[object z]"&&r(27)(Object.prototype,"toString",function(){return"[object "+e(this)+"]"},!0)},function(t,n,r){var e=r(1),i=r(188);e(e.G+e.F*(parseFloat!=i),{parseFloat:i})},function(t,n,r){var e=r(1),i=r(189);e(e.G+e.F*(parseInt!=i),{parseInt:i})},function(t,n,r){"use strict";var e,i,o,u,c=r(68),f=r(3),a=r(47),s=r(81),l=r(1),h=r(5),v=r(21),p=r(70),d=r(71),y=r(119),g=r(158).set,b=r(150)(),x=r(151),m=r(190),S=r(133),w=r(191),_="Promise",O=f.TypeError,E=f.process,M=E&&E.versions,P=M&&M.v8||"",j=f[_],F="process"==s(E),A=function(){},I=i=x.f,L=!!function(){try{var t=j.resolve(1),n=(t.constructor={})[r(7)("species")]=function(t){t(A,A)};return(F||"function"==typeof PromiseRejectionEvent)&&t.then(A)instanceof n&&0!==P.indexOf("6.6")&&-1===S.indexOf("Chrome/66")}catch(t){}}(),N=function(t){var n;return!(!h(t)||"function"!=typeof(n=t.then))&&n},T=function(s,r){if(!s._n){s._n=!0;var e=s._c;b(function(){for(var f=s._v,a=1==s._s,t=0,n=function(t){var n,r,e,i=a?t.ok:t.fail,o=t.resolve,u=t.reject,c=t.domain;try{i?(a||(2==s._h&&C(s),s._h=1),!0===i?n=f:(c&&c.enter(),n=i(f),c&&(c.exit(),e=!0)),n===t.promise?u(O("Promise-chain cycle")):(r=N(n))?r.call(n,o,u):o(n)):u(f)}catch(t){c&&!e&&c.exit(),u(t)}};e.length>t;)n(e[t++]);s._c=[],s._n=!1,r&&!s._h&&k(s)})}},k=function(o){g.call(f,function(){var t,n,r,e=o._v,i=R(o);if(i&&(t=m(function(){F?E.emit("unhandledRejection",e,o):(n=f.onunhandledrejection)?n({promise:o,reason:e}):(r=f.console)&&r.error&&r.error("Unhandled promise rejection",e)}),o._h=F||R(o)?2:1),o._a=void 0,i&&t.e)throw t.v})},R=function(t){return 1!==t._h&&0===(t._a||t._c).length},C=function(n){g.call(f,function(){var t;F?E.emit("rejectionHandled",n):(t=f.onrejectionhandled)&&t({promise:n,reason:n._v})})},D=function(t){var n=this;n._d||(n._d=!0,(n=n._w||n)._v=t,n._s=2,n._a||(n._a=n._c.slice()),T(n,!0))},G=function(t){var r,e=this;if(!e._d){e._d=!0,e=e._w||e;try{if(e===t)throw O("Promise can't be resolved itself");(r=N(t))?b(function(){var n={_w:e,_d:!1};try{r.call(t,a(G,n,1),a(D,n,1))}catch(t){D.call(n,t)}}):(e._v=t,e._s=1,T(e,!1))}catch(t){D.call({_w:e,_d:!1},t)}}};L||(j=function(t){p(this,j,_,"_h"),v(t),e.call(this);try{t(a(G,this,1),a(D,this,1))}catch(t){D.call(this,t)}},(e=function(t){this._c=[],this._a=void 0,this._s=0,this._d=!1,this._v=void 0,this._h=0,this._n=!1}).prototype=r(76)(j.prototype,{then:function(t,n){var r=I(y(this,j));return r.ok="function"!=typeof t||t,r.fail="function"==typeof n&&n,r.domain=F?E.domain:void 0,this._c.push(r),this._a&&this._a.push(r),this._s&&T(this,!1),r.promise},catch:function(t){return this.then(void 0,t)}}),o=function(){var t=new e;this.promise=t,this.resolve=a(G,t,1),this.reject=a(D,t,1)},x.f=I=function(t){return t===j||t===u?new o(t):i(t)}),l(l.G+l.W+l.F*!L,{Promise:j}),r(83)(j,_),r(77)(_),u=r(46)[_],l(l.S+l.F*!L,_,{reject:function(t){var n=I(this);return(0,n.reject)(t),n.promise}}),l(l.S+l.F*(c||!L),_,{resolve:function(t){return w(c&&this===u?j:this,t)}}),l(l.S+l.F*!(L&&r(125)(function(t){j.all(t).catch(A)})),_,{all:function(t){var u=this,n=I(u),c=n.resolve,f=n.reject,r=m(function(){var e=[],i=0,o=1;d(t,!1,function(t){var n=i++,r=!1;e.push(void 0),o++,u.resolve(t).then(function(t){r||(r=!0,e[n]=t,--o||c(e))},f)}),--o||c(e)});return r.e&&f(r.v),n.promise},race:function(t){var n=this,r=I(n),e=r.reject,i=m(function(){d(t,!1,function(t){n.resolve(t).then(r.resolve,e)})});return i.e&&e(i.v),r.promise}})},function(t,n,r){var e=r(1),o=r(21),u=r(2),c=(r(3).Reflect||{}).apply,f=Function.apply;e(e.S+e.F*!r(4)(function(){c(function(){})}),"Reflect",{apply:function(t,n,r){var e=o(t),i=u(r);return c?c(e,n,i):f.call(e,n,i)}})},function(t,n,r){var e=r(1),c=r(72),f=r(21),a=r(2),s=r(5),i=r(4),l=r(169),h=(r(3).Reflect||{}).construct,v=i(function(){function t(){}return!(h(function(){},[],t)instanceof t)}),p=!i(function(){h(function(){})});e(e.S+e.F*(v||p),"Reflect",{construct:function(t,n){f(t),a(n);var r=arguments.length<3?t:f(arguments[2]);if(p&&!v)return h(t,n,r);if(t==r){switch(n.length){case 0:return new t;case 1:return new t(n[0]);case 2:return new t(n[0],n[1]);case 3:return new t(n[0],n[1],n[2]);case 4:return new t(n[0],n[1],n[2],n[3])}var e=[null];return e.push.apply(e,n),new(l.apply(t,e))}var i=r.prototype,o=c(s(i)?i:Object.prototype),u=Function.apply.call(t,o,n);return s(u)?u:o}})},function(t,n,r){var e=r(11),i=r(1),o=r(2),u=r(53);i(i.S+i.F*r(4)(function(){Reflect.defineProperty(e.f({},1,{value:1}),1,{value:2})}),"Reflect",{defineProperty:function(t,n,r){o(t),n=u(n,!0),o(r);try{return e.f(t,n,r),!0}catch(t){return!1}}})},function(t,n,r){var e=r(1),i=r(31).f,o=r(2);e(e.S,"Reflect",{deleteProperty:function(t,n){var r=i(o(t),n);return!(r&&!r.configurable)&&delete t[n]}})},function(t,n,r){"use strict";var e=r(1),i=r(2),o=function(t){this._t=i(t),this._i=0;var n,r=this._k=[];for(n in t)r.push(n)};r(146)(o,"Object",function(){var t,n=this._k;do{if(this._i>=n.length)return{value:void 0,done:!0}}while(!((t=n[this._i++])in this._t));return{value:t,done:!1}}),e(e.S,"Reflect",{enumerate:function(t){return new o(t)}})},function(t,n,r){var e=r(31),i=r(1),o=r(2);i(i.S,"Reflect",{getOwnPropertyDescriptor:function(t,n){return e.f(o(t),n)}})},function(t,n,r){var e=r(1),i=r(32),o=r(2);e(e.S,"Reflect",{getPrototypeOf:function(t){return i(o(t))}})},function(t,n,r){var u=r(31),c=r(32),f=r(30),e=r(1),a=r(5),s=r(2);e(e.S,"Reflect",{get:function t(n,r){var e,i,o=arguments.length<3?n:arguments[2];return s(n)===o?n[r]:(e=u.f(n,r))?f(e,"value")?e.value:void 0!==e.get?e.get.call(o):void 0:a(i=c(n))?t(i,r,o):void 0}})},function(t,n,r){var e=r(1);e(e.S,"Reflect",{has:function(t,n){return n in t}})},function(t,n,r){var e=r(1),i=r(2),o=Object.isExtensible;e(e.S,"Reflect",{isExtensible:function(t){return i(t),!o||o(t)}})},function(t,n,r){var e=r(1);e(e.S,"Reflect",{ownKeys:r(187)})},function(t,n,r){var e=r(1),i=r(2),o=Object.preventExtensions;e(e.S,"Reflect",{preventExtensions:function(t){i(t);try{return o&&o(t),!0}catch(t){return!1}}})},function(t,n,r){var e=r(1),i=r(153);i&&e(e.S,"Reflect",{setPrototypeOf:function(t,n){i.check(t,n);try{return i.set(t,n),!0}catch(t){return!1}}})},function(t,n,r){var f=r(11),a=r(31),s=r(32),l=r(30),e=r(1),h=r(75),v=r(2),p=r(5);e(e.S,"Reflect",{set:function t(n,r,e){var i,o,u=arguments.length<4?n:arguments[3],c=a.f(v(n),r);if(!c){if(p(o=s(n)))return t(o,r,e,u);c=h(0)}if(l(c,"value")){if(!1===c.writable||!p(u))return!1;if(i=a.f(u,r)){if(i.get||i.set||!1===i.writable)return!1;i.value=e,f.f(u,r,i)}else f.f(u,r,h(0,e));return!0}return void 0!==c.set&&(c.set.call(u,e),!0)}})},function(t,n,r){var e=r(3),o=r(144),i=r(11).f,u=r(73).f,c=r(124),f=r(115),a=e.RegExp,s=a,l=a.prototype,h=/a/g,v=/a/g,p=new a(h)!==h;if(r(10)&&(!p||r(4)(function(){return v[r(7)("match")]=!1,a(h)!=h||a(v)==v||"/a/i"!=a(h,"i")}))){a=function(t,n){var r=this instanceof a,e=c(t),i=void 0===n;return!r&&e&&t.constructor===a&&i?t:o(p?new s(e&&!i?t.source:t,n):s((e=t instanceof a)?t.source:t,e&&i?f.call(t):n),r?this:l,a)};for(var d=function(n){n in a||i(a,n,{configurable:!0,get:function(){return s[n]},set:function(t){s[n]=t}})},y=u(s),g=0;y.length>g;)d(y[g++]);(l.constructor=a).prototype=l,r(27)(e,"RegExp",a)}r(77)("RegExp")},function(t,n,r){"use strict";var l=r(2),h=r(8),v=r(136),p=r(128);r(122)("match",1,function(e,i,a,s){return[function(t){var n=e(this),r=null==t?void 0:t[i];return void 0!==r?r.call(t,n):new RegExp(t)[i](String(n))},function(t){var n=s(a,t,this);if(n.done)return n.value;var r=l(t),e=String(this);if(!r.global)return p(r,e);for(var i,o=r.unicode,u=[],c=r.lastIndex=0;null!==(i=p(r,e));){var f=String(i[0]);""===(u[c]=f)&&(r.lastIndex=v(e,h(r.lastIndex),o)),c++}return 0===c?null:u}]})},function(t,n,r){"use strict";var O=r(2),e=r(17),E=r(8),M=r(49),P=r(136),j=r(128),F=Math.max,A=Math.min,h=Math.floor,v=/\$([$&`']|\d\d?|<[^>]*>)/g,p=/\$([$&`']|\d\d?)/g;r(122)("replace",2,function(i,o,S,w){function _(o,u,c,f,a,t){var s=c+o.length,l=f.length,n=p;return void 0!==a&&(a=e(a),n=v),S.call(t,n,function(t,n){var r;switch(n.charAt(0)){case"$":return"$";case"&":return o;case"`":return u.slice(0,c);case"'":return u.slice(s);case"<":r=a[n.slice(1,-1)];break;default:var e=+n;if(0===e)return t;if(l<e){var i=h(e/10);return 0===i?t:i<=l?void 0===f[i-1]?n.charAt(1):f[i-1]+n.charAt(1):t}r=f[e-1]}return void 0===r?"":r})}return[function(t,n){var r=i(this),e=null==t?void 0:t[o];return void 0!==e?e.call(t,r,n):S.call(String(r),t,n)},function(t,n){var r=w(S,t,this,n);if(r.done)return r.value;var e=O(t),i=String(this),o="function"==typeof n;o||(n=String(n));var u,c=e.global;if(c){var f=e.unicode;e.lastIndex=0}for(var a=[];;){var s=j(e,i);if(null===s)break;if(a.push(s),!c)break;""===String(s[0])&&(e.lastIndex=P(i,E(e.lastIndex),f))}for(var l="",h=0,v=0;v<a.length;v++){s=a[v];for(var p=String(s[0]),d=F(A(M(s.index),i.length),0),y=[],g=1;g<s.length;g++)y.push(void 0===(u=s[g])?u:String(u));var b=s.groups;if(o){var x=[p].concat(y,d,i);void 0!==b&&x.push(b);var m=String(n.apply(void 0,x))}else m=_(p,i,d,y,b,n);h<=d&&(l+=i.slice(h,d)+m,h=d+p.length)}return l+i.slice(h)}]})},function(t,n,r){"use strict";var f=r(2),a=r(192),s=r(128);r(122)("search",1,function(e,i,u,c){return[function(t){var n=e(this),r=null==t?void 0:t[i];return void 0!==r?r.call(t,n):new RegExp(t)[i](String(n))},function(t){var n=c(u,t,this);if(n.done)return n.value;var r=f(t),e=String(this),i=r.lastIndex;a(i,0)||(r.lastIndex=0);var o=s(r,e);return a(r.lastIndex,i)||(r.lastIndex=i),null===o?-1:o.index}]})},function(t,n,r){"use strict";var l=r(124),x=r(2),m=r(119),S=r(136),w=r(8),_=r(128),h=r(152),e=r(4),O=Math.min,v=[].push,u="split",p="length",d="lastIndex",E=4294967295,M=!e(function(){RegExp(E,"y")});r(122)("split",2,function(i,o,y,g){var b;return b="c"=="abbc"[u](/(b)*/)[1]||4!="test"[u](/(?:)/,-1)[p]||2!="ab"[u](/(?:ab)*/)[p]||4!="."[u](/(.?)(.?)/)[p]||1<"."[u](/()()/)[p]||""[u](/.?/)[p]?function(t,n){var r=String(this);if(void 0===t&&0===n)return[];if(!l(t))return y.call(r,t,n);for(var e,i,o,u=[],c=(t.ignoreCase?"i":"")+(t.multiline?"m":"")+(t.unicode?"u":"")+(t.sticky?"y":""),f=0,a=void 0===n?E:n>>>0,s=new RegExp(t.source,c+"g");(e=h.call(s,r))&&!(f<(i=s[d])&&(u.push(r.slice(f,e.index)),1<e[p]&&e.index<r[p]&&v.apply(u,e.slice(1)),o=e[0][p],f=i,u[p]>=a));)s[d]===e.index&&s[d]++;return f===r[p]?!o&&s.test("")||u.push(""):u.push(r.slice(f)),u[p]>a?u.slice(0,a):u}:"0"[u](void 0,0)[p]?function(t,n){return void 0===t&&0===n?[]:y.call(this,t,n)}:y,[function(t,n){var r=i(this),e=null==t?void 0:t[o];return void 0!==e?e.call(t,r,n):b.call(String(r),t,n)},function(t,n){var r=g(b,t,this,n,b!==y);if(r.done)return r.value;var e=x(t),i=String(this),o=m(e,RegExp),u=e.unicode,c=(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.unicode?"u":"")+(M?"y":"g"),f=new o(M?e:"^(?:"+e.source+")",c),a=void 0===n?E:n>>>0;if(0===a)return[];if(0===i.length)return null===_(f,i)?[i]:[];for(var s=0,l=0,h=[];l<i.length;){f.lastIndex=M?l:0;var v,p=_(f,M?i:i.slice(l));if(null===p||(v=O(w(f.lastIndex+(M?0:l)),i.length))===s)l=S(i,l,u);else{if(h.push(i.slice(s,l)),h.length===a)return h;for(var d=1;d<=p.length-1;d++)if(h.push(p[d]),h.length===a)return h;l=s=v}}return h.push(i.slice(s)),h}]})},function(t,n,r){"use strict";r(198);var e=r(2),i=r(115),o=r(10),u="toString",c=/./[u],f=function(t){r(27)(RegExp.prototype,u,t,!0)};r(4)(function(){return"/a/b"!=c.call({source:"a",flags:"b"})})?f(function(){var t=e(this);return"/".concat(t.source,"/","flags"in t?t.flags:!o&&t instanceof RegExp?i.call(t):void 0)}):c.name!=u&&f(function(){return c.call(this)})},function(t,n,r){"use strict";r(28)("anchor",function(n){return function(t){return n(this,"a","name",t)}})},function(t,n,r){"use strict";r(28)("big",function(t){return function(){return t(this,"big","","")}})},function(t,n,r){"use strict";r(28)("blink",function(t){return function(){return t(this,"blink","","")}})},function(t,n,r){"use strict";r(28)("bold",function(t){return function(){return t(this,"b","","")}})},function(t,n,r){"use strict";var e=r(1),i=r(131)(!1);e(e.P,"String",{codePointAt:function(t){return i(this,t)}})},function(t,n,r){"use strict";var e=r(1),u=r(8),c=r(155),f="endsWith",a=""[f];e(e.P+e.F*r(142)(f),"String",{endsWith:function(t){var n=c(this,t,f),r=1<arguments.length?arguments[1]:void 0,e=u(n.length),i=void 0===r?e:Math.min(u(r),e),o=String(t);return a?a.call(n,o,i):n.slice(i-o.length,i)===o}})},function(t,n,r){"use strict";r(28)("fixed",function(t){return function(){return t(this,"tt","","")}})},function(t,n,r){"use strict";r(28)("fontcolor",function(n){return function(t){return n(this,"font","color",t)}})},function(t,n,r){"use strict";r(28)("fontsize",function(n){return function(t){return n(this,"font","size",t)}})},function(t,n,r){var e=r(1),o=r(78),u=String.fromCharCode,i=String.fromCodePoint;e(e.S+e.F*(!!i&&1!=i.length),"String",{fromCodePoint:function(t){for(var n,r=[],e=arguments.length,i=0;i<e;){if(n=+arguments[i++],o(n,1114111)!==n)throw RangeError(n+" is not a valid code point");r.push(n<65536?u(n):u(55296+((n-=65536)>>10),n%1024+56320))}return r.join("")}})},function(t,n,r){"use strict";var e=r(1),i=r(155);e(e.P+e.F*r(142)("includes"),"String",{includes:function(t){return!!~i(this,t,"includes").indexOf(t,1<arguments.length?arguments[1]:void 0)}})},function(t,n,r){"use strict";r(28)("italics",function(t){return function(){return t(this,"i","","")}})},function(t,n,r){"use strict";var e=r(131)(!0);r(147)(String,"String",function(t){this._t=String(t),this._i=0},function(){var t,n=this._t,r=this._i;return r>=n.length?{value:void 0,done:!0}:(t=e(n,r),this._i+=t.length,{value:t,done:!1})})},function(t,n,r){"use strict";r(28)("link",function(n){return function(t){return n(this,"a","href",t)}})},function(t,n,r){var e=r(1),u=r(33),c=r(8);e(e.S,"String",{raw:function(t){for(var n=u(t.raw),r=c(n.length),e=arguments.length,i=[],o=0;o<r;)i.push(String(n[o++])),o<e&&i.push(String(arguments[o]));return i.join("")}})},function(t,n,r){var e=r(1);e(e.P,"String",{repeat:r(156)})},function(t,n,r){"use strict";r(28)("small",function(t){return function(){return t(this,"small","","")}})},function(t,n,r){"use strict";var e=r(1),i=r(8),o=r(155),u="startsWith",c=""[u];e(e.P+e.F*r(142)(u),"String",{startsWith:function(t){var n=o(this,t,u),r=i(Math.min(1<arguments.length?arguments[1]:void 0,n.length)),e=String(t);return c?c.call(n,e,r):n.slice(r,r+e.length)===e}})},function(t,n,r){"use strict";r(28)("strike",function(t){return function(){return t(this,"strike","","")}})},function(t,n,r){"use strict";r(28)("sub",function(t){return function(){return t(this,"sub","","")}})},function(t,n,r){"use strict";r(28)("sup",function(t){return function(){return t(this,"sup","","")}})},function(t,n,r){"use strict";r(84)("trim",function(t){return function(){return t(this,3)}})},function(t,n,r){"use strict";var e=r(3),u=r(30),i=r(10),o=r(1),c=r(27),f=r(69).KEY,a=r(4),s=r(118),l=r(83),h=r(79),v=r(7),p=r(195),d=r(160),y=r(218),g=r(123),b=r(2),x=r(5),m=r(17),S=r(33),w=r(53),_=r(75),O=r(72),E=r(184),M=r(31),P=r(127),j=r(11),F=r(74),A=M.f,I=j.f,L=E.f,N=e.Symbol,T=e.JSON,k=T&&T.stringify,R="prototype",C=v("_hidden"),D=v("toPrimitive"),G={}.propertyIsEnumerable,W=s("symbol-registry"),U=s("symbols"),V=s("op-symbols"),B=Object[R],q="function"==typeof N&&!!P.f,z=e.QObject,K=!z||!z[R]||!z[R].findChild,H=i&&a(function(){return 7!=O(I({},"a",{get:function(){return I(this,"a",{value:7}).a}})).a})?function(t,n,r){var e=A(B,n);e&&delete B[n],I(t,n,r),e&&t!==B&&I(B,n,e)}:I,J=function(t){var n=U[t]=O(N[R]);return n._k=t,n},$=q&&"symbol"==typeof N.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof N},Y=function(t,n,r){return t===B&&Y(V,n,r),b(t),n=w(n,!0),b(r),u(U,n)?(r.enumerable?(u(t,C)&&t[C][n]&&(t[C][n]=!1),r=O(r,{enumerable:_(0,!1)})):(u(t,C)||I(t,C,_(1,{})),t[C][n]=!0),H(t,n,r)):I(t,n,r)},X=function(t,n){b(t);for(var r,e=y(n=S(n)),i=0,o=e.length;i<o;)Y(t,r=e[i++],n[r]);return t},Q=function(t){var n=G.call(this,t=w(t,!0));return!(this===B&&u(U,t)&&!u(V,t))&&(!(n||!u(this,t)||!u(U,t)||u(this,C)&&this[C][t])||n)},Z=function(t,n){if(t=S(t),n=w(n,!0),t!==B||!u(U,n)||u(V,n)){var r=A(t,n);return!r||!u(U,n)||u(t,C)&&t[C][n]||(r.enumerable=!0),r}},tt=function(t){for(var n,r=L(S(t)),e=[],i=0;r.length>i;)u(U,n=r[i++])||n==C||n==f||e.push(n);return e},nt=function(t){for(var n,r=t===B,e=L(r?V:S(t)),i=[],o=0;e.length>o;)!u(U,n=e[o++])||r&&!u(B,n)||i.push(U[n]);return i};q||(c((N=function(){if(this instanceof N)throw TypeError("Symbol is not a constructor!");var n=h(0<arguments.length?arguments[0]:void 0),r=function(t){this===B&&r.call(V,t),u(this,C)&&u(this[C],n)&&(this[C][n]=!1),H(this,n,_(1,t))};return i&&K&&H(B,n,{configurable:!0,set:r}),J(n)})[R],"toString",function(){return this._k}),M.f=Z,j.f=Y,r(73).f=E.f=tt,r(117).f=Q,P.f=nt,i&&!r(68)&&c(B,"propertyIsEnumerable",Q,!0),p.f=function(t){return J(v(t))}),o(o.G+o.W+o.F*!q,{Symbol:N});for(var rt="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),et=0;rt.length>et;)v(rt[et++]);for(var it=F(v.store),ot=0;it.length>ot;)d(it[ot++]);o(o.S+o.F*!q,"Symbol",{for:function(t){return u(W,t+="")?W[t]:W[t]=N(t)},keyFor:function(t){if(!$(t))throw TypeError(t+" is not a symbol!");for(var n in W)if(W[n]===t)return n},useSetter:function(){K=!0},useSimple:function(){K=!1}}),o(o.S+o.F*!q,"Object",{create:function(t,n){return void 0===n?O(t):X(O(t),n)},defineProperty:Y,defineProperties:X,getOwnPropertyDescriptor:Z,getOwnPropertyNames:tt,getOwnPropertySymbols:nt});var ut=a(function(){P.f(1)});o(o.S+o.F*ut,"Object",{getOwnPropertySymbols:function(t){return P.f(m(t))}}),T&&o(o.S+o.F*(!q||a(function(){var t=N();return"[null]"!=k([t])||"{}"!=k({a:t})||"{}"!=k(Object(t))})),"JSON",{stringify:function(t){for(var n,r,e=[t],i=1;arguments.length>i;)e.push(arguments[i++]);if(r=n=e[1],(x(n)||void 0!==t)&&!$(t))return g(n)||(n=function(t,n){if("function"==typeof r&&(n=r.call(this,t,n)),!$(n))return n}),e[1]=n,k.apply(T,e)}}),N[R][D]||r(26)(N[R],D,N[R].valueOf),l(N,"Symbol"),l(Math,"Math",!0),l(e.JSON,"JSON",!0)},function(t,n,r){"use strict";var e=r(1),i=r(132),o=r(159),a=r(2),s=r(78),l=r(8),u=r(5),c=r(3).ArrayBuffer,h=r(119),v=o.ArrayBuffer,p=o.DataView,f=i.ABV&&c.isView,d=v.prototype.slice,y=i.VIEW,g="ArrayBuffer";e(e.G+e.W+e.F*(c!==v),{ArrayBuffer:v}),e(e.S+e.F*!i.CONSTR,g,{isView:function(t){return f&&f(t)||u(t)&&y in t}}),e(e.P+e.U+e.F*r(4)(function(){return!new v(2).slice(1,void 0).byteLength}),g,{slice:function(t,n){if(void 0!==d&&void 0===n)return d.call(a(this),t);for(var r=a(this).byteLength,e=s(t,r),i=s(void 0===n?r:n,r),o=new(h(this,v))(l(i-e)),u=new p(this),c=new p(o),f=0;e<i;)c.setUint8(f++,u.getUint8(e++));return o}}),r(77)(g)},function(t,n,r){var e=r(1);e(e.G+e.W+e.F*!r(132).ABV,{DataView:r(159).DataView})},function(t,n,r){r(57)("Float32",4,function(e){return function(t,n,r){return e(this,t,n,r)}})},function(t,n,r){r(57)("Float64",8,function(e){return function(t,n,r){return e(this,t,n,r)}})},function(t,n,r){r(57)("Int16",2,function(e){return function(t,n,r){return e(this,t,n,r)}})},function(t,n,r){r(57)("Int32",4,function(e){return function(t,n,r){return e(this,t,n,r)}})},function(t,n,r){r(57)("Int8",1,function(e){return function(t,n,r){return e(this,t,n,r)}})},function(t,n,r){r(57)("Uint16",2,function(e){return function(t,n,r){return e(this,t,n,r)}})},function(t,n,r){r(57)("Uint32",4,function(e){return function(t,n,r){return e(this,t,n,r)}})},function(t,n,r){r(57)("Uint8",1,function(e){return function(t,n,r){return e(this,t,n,r)}})},function(t,n,r){r(57)("Uint8",1,function(e){return function(t,n,r){return e(this,t,n,r)}},!0)},function(t,n,r){"use strict";var e=r(172),i=r(80);r(121)("WeakSet",function(t){return function(){return t(this,0<arguments.length?arguments[0]:void 0)}},{add:function(t){return e.def(i(this,"WeakSet"),t,!0)}},e,!1,!0)},function(t,n,r){"use strict";var e=r(1),i=r(173),o=r(17),u=r(8),c=r(21),f=r(138);e(e.P,"Array",{flatMap:function(t){var n,r,e=o(this);return c(t),n=u(e.length),r=f(e,0),i(r,e,e,n,0,1,t,arguments[1]),r}}),r(67)("flatMap")},function(t,n,r){"use strict";var e=r(1),i=r(173),o=r(17),u=r(8),c=r(49),f=r(138);e(e.P,"Array",{flatten:function(){var t=arguments[0],n=o(this),r=u(n.length),e=f(n,0);return i(e,n,n,r,0,void 0===t?1:c(t)),e}}),r(67)("flatten")},function(t,n,r){"use strict";var e=r(1),i=r(120)(!0);e(e.P,"Array",{includes:function(t){return i(this,t,1<arguments.length?arguments[1]:void 0)}}),r(67)("includes")},function(t,n,r){var e=r(1),i=r(150)(),o=r(3).process,u="process"==r(45)(o);e(e.G,{asap:function(t){var n=u&&o.domain;i(n?n.bind(t):t)}})},function(t,n,r){var e=r(1),i=r(45);e(e.S,"Error",{isError:function(t){return"Error"===i(t)}})},function(t,n,r){var e=r(1);e(e.G,{global:r(3)})},function(t,n,r){r(129)("Map")},function(t,n,r){r(130)("Map")},function(t,n,r){var e=r(1);e(e.P+e.R,"Map",{toJSON:r(171)("Map")})},function(t,n,r){var e=r(1);e(e.S,"Math",{clamp:function(t,n,r){return Math.min(r,Math.max(n,t))}})},function(t,n,r){var e=r(1);e(e.S,"Math",{DEG_PER_RAD:Math.PI/180})},function(t,n,r){var e=r(1),i=180/Math.PI;e(e.S,"Math",{degrees:function(t){return t*i}})},function(t,n,r){var e=r(1),o=r(181),u=r(179);e(e.S,"Math",{fscale:function(t,n,r,e,i){return u(o(t,n,r,e,i))}})},function(t,n,r){var e=r(1);e(e.S,"Math",{iaddh:function(t,n,r,e){var i=t>>>0,o=r>>>0;return(n>>>0)+(e>>>0)+((i&o|(i|o)&~(i+o>>>0))>>>31)|0}})},function(t,n,r){var e=r(1);e(e.S,"Math",{imulh:function(t,n){var r=+t,e=+n,i=65535&r,o=65535&e,u=r>>16,c=e>>16,f=(u*o>>>0)+(i*o>>>16);return u*c+(f>>16)+((i*c>>>0)+(65535&f)>>16)}})},function(t,n,r){var e=r(1);e(e.S,"Math",{isubh:function(t,n,r,e){var i=t>>>0,o=r>>>0;return(n>>>0)-(e>>>0)-((~i&o|~(i^o)&i-o>>>0)>>>31)|0}})},function(t,n,r){var e=r(1);e(e.S,"Math",{RAD_PER_DEG:180/Math.PI})},function(t,n,r){var e=r(1),i=Math.PI/180;e(e.S,"Math",{radians:function(t){return t*i}})},function(t,n,r){var e=r(1);e(e.S,"Math",{scale:r(181)})},function(t,n,r){var e=r(1);e(e.S,"Math",{signbit:function(t){return(t=+t)!=t?t:0==t?1/t==1/0:0<t}})},function(t,n,r){var e=r(1);e(e.S,"Math",{umulh:function(t,n){var r=+t,e=+n,i=65535&r,o=65535&e,u=r>>>16,c=e>>>16,f=(u*o>>>0)+(i*o>>>16);return u*c+(f>>>16)+((i*c>>>0)+(65535&f)>>>16)}})},function(t,n,r){"use strict";var e=r(1),i=r(17),o=r(21),u=r(11);r(10)&&e(e.P+r(126),"Object",{__defineGetter__:function(t,n){u.f(i(this),t,{get:o(n),enumerable:!0,configurable:!0})}})},function(t,n,r){"use strict";var e=r(1),i=r(17),o=r(21),u=r(11);r(10)&&e(e.P+r(126),"Object",{__defineSetter__:function(t,n){u.f(i(this),t,{set:o(n),enumerable:!0,configurable:!0})}})},function(t,n,r){var e=r(1),i=r(186)(!0);e(e.S,"Object",{entries:function(t){return i(t)}})},function(t,n,r){var e=r(1),f=r(187),a=r(33),s=r(31),l=r(139);e(e.S,"Object",{getOwnPropertyDescriptors:function(t){for(var n,r,e=a(t),i=s.f,o=f(e),u={},c=0;o.length>c;)void 0!==(r=i(e,n=o[c++]))&&l(u,n,r);return u}})},function(t,n,r){"use strict";var e=r(1),i=r(17),o=r(53),u=r(32),c=r(31).f;r(10)&&e(e.P+r(126),"Object",{__lookupGetter__:function(t){var n,r=i(this),e=o(t,!0);do{if(n=c(r,e))return n.get}while(r=u(r))}})},function(t,n,r){"use strict";var e=r(1),i=r(17),o=r(53),u=r(32),c=r(31).f;r(10)&&e(e.P+r(126),"Object",{__lookupSetter__:function(t){var n,r=i(this),e=o(t,!0);do{if(n=c(r,e))return n.set}while(r=u(r))}})},function(t,n,r){var e=r(1),i=r(186)(!1);e(e.S,"Object",{values:function(t){return i(t)}})},function(t,n,r){"use strict";var e=r(1),o=r(3),u=r(46),i=r(150)(),c=r(7)("observable"),f=r(21),a=r(2),s=r(70),l=r(76),h=r(26),v=r(71),p=v.RETURN,d=function(t){return null==t?void 0:f(t)},y=function(t){var n=t._c;n&&(t._c=void 0,n())},g=function(t){return void 0===t._o},b=function(t){g(t)||(t._o=void 0,y(t))},x=function(t,n){a(t),this._c=void 0,this._o=t,t=new m(this);try{var r=n(t),e=r;null!=r&&("function"==typeof r.unsubscribe?r=function(){e.unsubscribe()}:f(r),this._c=r)}catch(n){return void t.error(n)}g(this)&&y(this)};x.prototype=l({},{unsubscribe:function(){b(this)}});var m=function(t){this._s=t};m.prototype=l({},{next:function(t){var n=this._s;if(!g(n)){var r=n._o;try{var e=d(r.next);if(e)return e.call(r,t)}catch(t){try{b(n)}finally{throw t}}}},error:function(t){var n=this._s;if(g(n))throw t;var r=n._o;n._o=void 0;try{var e=d(r.error);if(!e)throw t;t=e.call(r,t)}catch(t){try{y(n)}finally{throw t}}return y(n),t},complete:function(t){var n=this._s;if(!g(n)){var r=n._o;n._o=void 0;try{var e=d(r.complete);t=e?e.call(r,t):void 0}catch(t){try{y(n)}finally{throw t}}return y(n),t}}});var S=function(t){s(this,S,"Observable","_f")._f=f(t)};l(S.prototype,{subscribe:function(t){return new x(t,this._f)},forEach:function(e){var i=this;return new(u.Promise||o.Promise)(function(t,n){f(e);var r=i.subscribe({next:function(t){try{return e(t)}catch(t){n(t),r.unsubscribe()}},error:n,complete:t})})}}),l(S,{from:function(t){var n="function"==typeof this?this:S,r=d(a(t)[c]);if(r){var e=a(r.call(t));return e.constructor===n?e:new n(function(t){return e.subscribe(t)})}return new n(function(n){var r=!1;return i(function(){if(!r){try{if(v(t,!1,function(t){if(n.next(t),r)return p})===p)return}catch(t){if(r)throw t;return void n.error(t)}n.complete()}}),function(){r=!0}})},of:function(){for(var t=0,n=arguments.length,e=new Array(n);t<n;)e[t]=arguments[t++];return new("function"==typeof this?this:S)(function(n){var r=!1;return i(function(){if(!r){for(var t=0;t<e.length;++t)if(n.next(e[t]),r)return;n.complete()}}),function(){r=!0}})}}),h(S.prototype,c,function(){return this}),e(e.G,{Observable:S}),r(77)("Observable")},function(t,n,r){"use strict";var e=r(1),i=r(46),o=r(3),u=r(119),c=r(191);e(e.P+e.R,"Promise",{finally:function(n){var r=u(this,i.Promise||o.Promise),t="function"==typeof n;return this.then(t?function(t){return c(r,n()).then(function(){return t})}:n,t?function(t){return c(r,n()).then(function(){throw t})}:n)}})},function(t,n,r){"use strict";var e=r(1),i=r(151),o=r(190);e(e.S,"Promise",{try:function(t){var n=i.f(this),r=o(t);return(r.e?n.reject:n.resolve)(r.v),n.promise}})},function(t,n,r){var e=r(56),i=r(2),o=e.key,u=e.set;e.exp({defineMetadata:function(t,n,r,e){u(t,n,i(r),o(e))}})},function(t,n,r){var e=r(56),o=r(2),u=e.key,c=e.map,f=e.store;e.exp({deleteMetadata:function(t,n){var r=arguments.length<3?void 0:u(arguments[2]),e=c(o(n),r,!1);if(void 0===e||!e.delete(t))return!1;if(e.size)return!0;var i=f.get(n);return i.delete(r),!!i.size||f.delete(n)}})},function(t,n,r){var o=r(199),u=r(167),e=r(56),i=r(2),c=r(32),f=e.keys,a=e.key,s=function(t,n){var r=f(t,n),e=c(t);if(null===e)return r;var i=s(e,n);return i.length?r.length?u(new o(r.concat(i))):i:r};e.exp({getMetadataKeys:function(t){return s(i(t),arguments.length<2?void 0:a(arguments[1]))}})},function(t,n,r){var e=r(56),i=r(2),o=r(32),u=e.has,c=e.get,f=e.key,a=function(t,n,r){if(u(t,n,r))return c(t,n,r);var e=o(n);return null!==e?a(t,e,r):void 0};e.exp({getMetadata:function(t,n){return a(t,i(n),arguments.length<3?void 0:f(arguments[2]))}})},function(t,n,r){var e=r(56),i=r(2),o=e.keys,u=e.key;e.exp({getOwnMetadataKeys:function(t){return o(i(t),arguments.length<2?void 0:u(arguments[1]))}})},function(t,n,r){var e=r(56),i=r(2),o=e.get,u=e.key;e.exp({getOwnMetadata:function(t,n){return o(t,i(n),arguments.length<3?void 0:u(arguments[2]))}})},function(t,n,r){var e=r(56),i=r(2),o=r(32),u=e.has,c=e.key,f=function(t,n,r){if(u(t,n,r))return!0;var e=o(n);return null!==e&&f(t,e,r)};e.exp({hasMetadata:function(t,n){return f(t,i(n),arguments.length<3?void 0:c(arguments[2]))}})},function(t,n,r){var e=r(56),i=r(2),o=e.has,u=e.key;e.exp({hasOwnMetadata:function(t,n){return o(t,i(n),arguments.length<3?void 0:u(arguments[2]))}})},function(t,n,r){var e=r(56),i=r(2),o=r(21),u=e.key,c=e.set;e.exp({metadata:function(r,e){return function(t,n){c(r,e,(void 0!==n?i:o)(t),u(n))}}})},function(t,n,r){r(129)("Set")},function(t,n,r){r(130)("Set")},function(t,n,r){var e=r(1);e(e.P+e.R,"Set",{toJSON:r(171)("Set")})},function(t,n,r){"use strict";var e=r(1),i=r(131)(!0);e(e.P,"String",{at:function(t){return i(this,t)}})},function(t,n,r){"use strict";var e=r(1),i=r(51),o=r(8),u=r(124),c=r(115),f=RegExp.prototype,a=function(t,n){this._r=t,this._s=n};r(146)(a,"RegExp String",function(){var t=this._r.exec(this._s);return{value:t,done:null===t}}),e(e.P,"String",{matchAll:function(t){if(i(this),!u(t))throw TypeError(t+" is not a regexp!");var n=String(this),r="flags"in f?String(t.flags):c.call(t),e=new RegExp(t.source,~r.indexOf("g")?r:"g"+r);return e.lastIndex=o(t.lastIndex),new a(e,n)}})},function(t,n,r){"use strict";var e=r(1),i=r(193),o=r(133),u=/Version\/10\.\d+(\.\d+)?( Mobile\/\w+)? Safari\//.test(o);e(e.P+e.F*u,"String",{padEnd:function(t){return i(this,t,1<arguments.length?arguments[1]:void 0,!1)}})},function(t,n,r){"use strict";var e=r(1),i=r(193),o=r(133),u=/Version\/10\.\d+(\.\d+)?( Mobile\/\w+)? Safari\//.test(o);e(e.P+e.F*u,"String",{padStart:function(t){return i(this,t,1<arguments.length?arguments[1]:void 0,!0)}})},function(t,n,r){"use strict";r(84)("trimLeft",function(t){return function(){return t(this,1)}},"trimStart")},function(t,n,r){"use strict";r(84)("trimRight",function(t){return function(){return t(this,2)}},"trimEnd")},function(t,n,r){r(160)("asyncIterator")},function(t,n,r){r(160)("observable")},function(t,n,r){var e=r(1);e(e.S,"System",{global:r(3)})},function(t,n,r){r(129)("WeakMap")},function(t,n,r){r(130)("WeakMap")},function(t,n,r){r(129)("WeakSet")},function(t,n,r){r(130)("WeakSet")},function(t,n,r){for(var e=r(162),i=r(74),o=r(27),u=r(3),c=r(26),f=r(82),a=r(7),s=a("iterator"),l=a("toStringTag"),h=f.Array,v={CSSRuleList:!0,CSSStyleDeclaration:!1,CSSValueList:!1,ClientRectList:!1,DOMRectList:!1,DOMStringList:!1,DOMTokenList:!0,DataTransferItemList:!1,FileList:!1,HTMLAllCollection:!1,HTMLCollection:!1,HTMLFormElement:!1,HTMLSelectElement:!1,MediaList:!0,MimeTypeArray:!1,NamedNodeMap:!1,NodeList:!0,PaintRequestList:!1,Plugin:!1,PluginArray:!1,SVGLengthList:!1,SVGNumberList:!1,SVGPathSegList:!1,SVGPointList:!1,SVGStringList:!1,SVGTransformList:!1,SourceBufferList:!1,StyleSheetList:!0,TextTrackCueList:!1,TextTrackList:!1,TouchList:!1},p=i(v),d=0;d<p.length;d++){var y,g=p[d],b=v[g],x=u[g],m=x&&x.prototype;if(m&&(m[s]||c(m,s,h),m[l]||c(m,l,g),f[g]=h,b))for(y in e)m[y]||o(m,y,e[y],!0)}},function(t,n,r){var e=r(1),i=r(158);e(e.G+e.B,{setImmediate:i.set,clearImmediate:i.clear})},function(t,n,r){var e=r(3),i=r(1),o=r(133),u=[].slice,c=/MSIE .\./.test(o),f=function(i){return function(t,n){var r=2<arguments.length,e=!!r&&u.call(arguments,2);return i(r?function(){("function"==typeof t?t:Function(t)).apply(this,e)}:t,n)}};i(i.G+i.B+i.F*c,{setTimeout:f(e.setTimeout),setInterval:f(e.setInterval)})},function(t,n,r){r(341),r(280),r(282),r(281),r(284),r(286),r(291),r(285),r(283),r(293),r(292),r(288),r(289),r(287),r(279),r(290),r(294),r(295),r(247),r(249),r(248),r(297),r(296),r(267),r(277),r(278),r(268),r(269),r(270),r(271),r(272),r(273),r(274),r(275),r(276),r(250),r(251),r(252),r(253),r(254),r(255),r(256),r(257),r(258),r(259),r(260),r(261),r(262),r(263),r(264),r(265),r(266),r(328),r(333),r(340),r(331),r(323),r(324),r(329),r(334),r(336),r(319),r(320),r(321),r(322),r(325),r(326),r(327),r(330),r(332),r(335),r(337),r(338),r(339),r(242),r(244),r(243),r(246),r(245),r(231),r(229),r(235),r(232),r(238),r(240),r(228),r(234),r(225),r(239),r(223),r(237),r(236),r(230),r(233),r(222),r(224),r(227),r(226),r(241),r(162),r(313),r(197),r(318),r(198),r(314),r(315),r(316),r(317),r(298),r(196),r(199),r(200),r(353),r(342),r(343),r(348),r(351),r(352),r(346),r(349),r(347),r(350),r(344),r(345),r(299),r(300),r(301),r(302),r(303),r(306),r(304),r(305),r(307),r(308),r(309),r(310),r(312),r(311),r(356),r(354),r(355),r(397),r(400),r(399),r(401),r(402),r(398),r(403),r(404),r(378),r(381),r(377),r(375),r(376),r(379),r(380),r(362),r(396),r(361),r(395),r(407),r(409),r(360),r(394),r(406),r(408),r(359),r(405),r(358),r(363),r(364),r(365),r(366),r(367),r(369),r(368),r(370),r(371),r(372),r(374),r(373),r(383),r(384),r(385),r(386),r(388),r(387),r(390),r(389),r(391),r(392),r(393),r(357),r(382),r(412),r(411),r(410),t.exports=r(46)},function(t,n){t.exports=function(t,n){if("string"==typeof n)return t.insertAdjacentHTML("afterend",n);var r=t.nextSibling;return r?t.parentNode.insertBefore(n,r):t.parentNode.appendChild(n)}}])</script><script src="/blog/./main.a5fda8.js"></script><script>!function(){var e,t;e="/blog/slider.27463f.js",t=document.createElement("script"),document.getElementsByTagName("body")[0].appendChild(t),t.setAttribute("src",e)}()</script>



<!--  -->

<script>
  /* 标签页标题切换 */
  var originTitle = document.title;
  var titleTime;
  document.addEventListener("visibilitychange", function () {
    if (document.hidden) {
      document.title = "(つェ⊂) 我藏好了哦~ " + originTitle;
      clearTimeout(titleTime);
    } else {
      document.title = "(*´∇｀*) 被你发现啦~ " + originTitle;
      titleTime = setTimeout(function () {
        document.title = originTitle;
      }, 2000);
    }
  });
</script>


    
<div class="tools-col" q-class="show:isShow,hide:isShow|isFalse" q-on="click:stop(e)">
  <div class="tools-nav header-menu">
    
    
      
      
      
    
      
      
      
    
      
      
      
    
    

    <ul style="width: 70%">
    
    
      
      <li style="width: 33.333333333333336%" q-on="click: openSlider(e, 'innerArchive')"><a href="javascript:void(0)" q-class="active:innerArchive">所有文章</a></li>
      
        
      
      <li style="width: 33.333333333333336%" q-on="click: openSlider(e, 'friends')"><a href="javascript:void(0)" q-class="active:friends">友链</a></li>
      
        
      
      <li style="width: 33.333333333333336%" q-on="click: openSlider(e, 'aboutme')"><a href="javascript:void(0)" q-class="active:aboutme">关于我</a></li>
      
        
    </ul>
  </div>
  <div class="tools-wrap">
    
    	<section class="tools-section tools-section-all" q-show="innerArchive">
        <div class="search-wrap">
          <input class="search-ipt" q-model="search" type="text" placeholder="find something…">
          <i class="icon-search icon" q-show="search|isEmptyStr"></i>
          <i class="icon-close icon" q-show="search|isNotEmptyStr" q-on="click:clearChose(e)"></i>
        </div>
        <div class="widget tagcloud search-tag">
          <p class="search-tag-wording">tag:</p>
          <label class="search-switch">
            <input type="checkbox" q-on="click:toggleTag(e)" q-attr="checked:showTags">
          </label>
          <ul class="article-tag-list" q-show="showTags">
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color1">alios</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color3">目录</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color2">MT7688</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color5">hexo</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color2">视频监控系统</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color4">文件io编程实战</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color4">Linux系统编程 入门篇</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color2">文件io缓存与内存映射</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color3">打通进程与终端的任督二脉</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color1">进程间通信</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color2">从零实现一个shell</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color3">多线程编程入门</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color1">时间管理和定时器编程</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color5">使用c语言实现协程</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color1">程序的编译连接和运行</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color2">堆栈内存管理</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color4">Linux内核中的GNU C扩展语法</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color5">嵌入式数据结构和Linux面向对象思想</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color3">数据存储于指针</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color5">c语言的模块化编程</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color5">C语言的模块化编程</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color1">CPU和操作系统入门</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color2">OpenHarmony</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color2">Linux第三方库开发</a>
              </li>
            
            <div class="clearfix"></div>
          </ul>
        </div>
        <ul class="search-ul">
          <p q-show="jsonFail" style="padding: 20px; font-size: 12px;">
            缺失模块。<br/>1、请确保node版本大于6.2<br/>2、在博客根目录（注意不是yilia-plus根目录）执行以下命令：<br/> npm i hexo-generator-json-content --save<br/><br/>
            3、在根目录_config.yml里添加配置：
<pre style="font-size: 12px;" q-show="jsonFail">
  jsonContent:
    meta: false
    pages: false
    posts:
      title: true
      date: true
      path: true
      text: false
      raw: false
      content: false
      slug: false
      updated: false
      comments: false
      link: false
      permalink: false
      excerpt: false
      categories: false
      tags: true
</pre>
          </p>
          <li class="search-li" q-repeat="items" q-show="isShow">
            <a q-attr="href:path|urlformat" class="search-title"><i class="icon-quo-left icon"></i><span q-text="title"></span></a>
            <p class="search-time">
              <i class="icon-calendar icon"></i>
              <span q-text="date|dateformat"></span>
            </p>
            <p class="search-tag">
              <i class="icon-price-tags icon"></i>
              <span q-repeat="tags" q-on="click:choseTag(e, name)" q-text="name|tagformat"></span>
            </p>
          </li>
        </ul>
    	</section>
    

    
    	<section class="tools-section tools-section-friends" q-show="friends">
  		
        <ul class="search-ul">
          
            <li class="search-li">
              <a href="https://gitee.com/yuzhongmeng" target="_blank" 
                class="search-title" >
                
                  <i class="icon-link icon"></i>
                
                码云
              </a>
            </li>
          
            <li class="search-li">
              <a href="https://blog.csdn.net/yzm65580952" target="_blank" 
                class="search-title" >
                
                  <i class="icon-link icon"></i>
                
                CSDN
              </a>
            </li>
          
            <li class="search-li">
              <a href="https://github.com/yzm65580952" target="_blank" 
                class="search-title" >
                
                  <i class="icon-link icon"></i>
                
                GitHub
              </a>
            </li>
          
        </ul>
  		
    	</section>
    

    
    	<section class="tools-section tools-section-me" q-show="aboutme">
        
          
  	  		<div class="aboutme-wrap" id="aboutme">主要涉及技术：<br>智能网关开发、Linux应用编程、<br>Linux系统编程、<br><br>openwrt框架、stm32开发<br><br>无线技术爱好者、开源爱好者<br><br>联系QQ:619372559<br><br>很惭愧<br><br>只做了一点微小的工作<br>谢谢大家</div>
  	  	
    	</section>
    
  </div>
  
</div>
    <!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

    <!-- Background of PhotoSwipe. 
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>

    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">

        <!-- Container that holds slides. 
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>

        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">

            <div class="pswp__top-bar">

                <!--  Controls are self-explanatory. Order can be changed. -->

                <div class="pswp__counter"></div>

                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

                <button class="pswp__button pswp__button--share" style="display:none" title="Share"></button>

                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                      <div class="pswp__preloader__cut">
                        <div class="pswp__preloader__donut"></div>
                      </div>
                    </div>
                </div>
            </div>

            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div> 
            </div>

            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>

            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>

            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>

        </div>

    </div>

</div>
  </div>

  
  
<script type="text/javascript" src="/blog/plugins/activate-power-mode/activate-power-mode.js"></script>
<script>
  POWERMODE.colorful = true; // make power mode colorful
  POWERMODE.shake = false; // turn off shake
  document.body.addEventListener('input', POWERMODE);
</script>

  
  <!-- <script async type="text/javascript" size="90" alpha="0.2" zIndex="0" src="/blog/plugins/ribbon.js/ribbon.min.js"></script> -->
  
  
    <script type="text/javascript" src="/blog/plugins/live2d-widget.js/L2Dwidget.min.js"></script>
<script type="text/javascript">
  /**
   * 完整配置请参考：https://l2dwidget.js.org/docs/class/src/index.js~L2Dwidget.html#instance-method-init
   */
  var pluginModelPath = "assets/", // 模型的文件路径，无需更改
    pluginRootPath = "/blog/live2d_models/"; // 插件的路径，无需更改
  //特定的模型json文件名称
  var modelPathJson = {
    "epsilon2_1": "Epsilon2.1",
    "gf": "Gantzert_Felixander",
    "haru/01": "haru01",
    "haru/02": "haru02",
    "nietzsche": "nietzche"
  }

  
    var modelName = "hibiki";
  

  var modelJsonPath = "";
  if (modelPathJson[modelName]) {
    modelJsonPath = pluginRootPath + modelName + "/" + pluginModelPath + modelPathJson[modelName] +
      ".model.json";
  } else {
    modelJsonPath = pluginRootPath + modelName + "/" + pluginModelPath + modelName + ".model.json";
  }
  L2Dwidget.init({
    model: {
      jsonPath: modelJsonPath
    },
    display: {
       position: "right", 
       width: 145, 
       height: 315, 
       hOffset: 50, 
      
    },
    mobile: {
       show: false, 
       scale: 0.6 
    },
    react: {
       opacity: 0.8 
    }
  })

</script>

  
  
</body>

</html>
